Day21_学点儿JavaEE__过滤器Filter(登录验证、编码处理)

1 为什么要使用过滤器

昨天已经总结过

当然,这仅仅是完成了一个简单的登录过程,即完成判断输入信息是否和数据库信息相匹配的操作,但是仍然可以通过直接输入地址的方式,在不登录的情况下访问相应的页面。而我们实际生活中的没登录的情况下,很多页面是无法访问的,要实现这样的效果,我们可以在每个页面都增加一个判断Session中的用户名密码是否和数据库匹配的操作,但是未免也太麻烦了 点。通过过滤器Filter,可以很简单地实现这个效果

项目开发中,经常会用到重复代码的实现。

  1. 请求每个servlet都要设置编码
  2. 判断用户是否登录,只有登录了才有操作权限。

2 过滤器相关API

interface Filter 过滤器核心接口

  1. init(FilterConfig filterConfig)
    初始化方法,在服务器启动的时候就执行
  2. doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    过滤器拦截的业务逻辑处理
  3. destroy()
    销毁过滤器实例的时候调用

interface FilterChain 过滤链

doFilter(ServletRequest request, ServletResponse response)

执行下一个过滤器或放行(访问servlet)

3 案例一:用过滤器完成登录

java 复制代码
// /*  拦截所有的请求
@WebFilter(filterName = "login", urlPatterns = "/*")
public class LoginFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
        System.out.println("LoginFilter.init");
    }

    // ServletRequest servletRequest = new HttpServletRequest()
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("LoginFilter.doFilter");
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        String servletPath = request.getServletPath();
        System.out.println("servletPath:" + servletPath);
        String method = request.getParameter("method");
        //这是请求是要去完成登录的,不需要执行后面验证是否登录的流程
        if (servletPath.endsWith(".jpg")
                || servletPath.endsWith(".png")
                || servletPath.endsWith(".js")
                || servletPath.endsWith(".css")
                || servletPath.equals("/login.jsp")
                || servletPath.equals("/user") && "login".equals(method)) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }

        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user");
        if (user == null) {
            response.sendRedirect("/login.jsp");
            return;
        }

        //加了这句话代表方行,继续往后执行,
        //如果还有filter就访问后面filter,没有filter,就可以访问后台资源
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
        System.out.println("LoginFilter.destroy");
    }
}

4 案例二:用过滤器处理POST请求乱码问题

由于在案例一中的登录过滤器中调用了request.getParameter("method")方法,这会导致之前在其他Servlet中设置的request.setCharacterEncoding("UTF-8");处理乱码失效(因为Filter会先执行),所以我们可以再单独设置一个处理乱码的Filter。

java 复制代码
@WebFilter(filterName = "encoding", urlPatterns = "/*")
public class EncodingFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("EncodingFilter.doFilter");
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        // 这个method是get还是post
        String method = request.getMethod();
        // 解决post请求乱码问题
        if ("post".equalsIgnoreCase(method)) {
            request.setCharacterEncoding("UTF-8");
        }

        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}

5 web.xml配置servlet和过滤器(多个Filter优先级)

servlet和filter除了用注解方式配置,还可以使用xml的方式配置

WEB-INF/web.xml是Web项目的核心配置文件

html 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">



    <!--
        @WebServlet("/student")
        public class StudentServlet extends HttpServlet { }
    -->              
    <servlet>
        <servlet-name>studentServlet</servlet-name>
        <servlet-class>com.situ.web.controller.StudentServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>studentServlet</servlet-name>
        <url-pattern>/student</url-pattern>
    </servlet-mapping>
    



    <filter>
        <filter-name>encoding</filter-name>
        <filter-class>com.situ.web.filter.EncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>login</filter-name>
        <filter-class>com.situ.web.filter.LoginFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>login</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

先设置的Filter优先级高于后设置下的Filter优先级。在web.xml配置servlet和Filter的话,要把@@WebServlet("/student")@WebFilter(filterName = "login", urlPatterns = "/*")注解形式的语句注释掉,不然会有冲突。

代码

Day20_复制粘贴快速开发(课程表)、CookieDemo、Filter登录过滤及放行、教师薪资显示0.0
Day21_过滤器处理POST乱码,JS DOM、点击事件,JQuery

相关推荐
全栈开发圈几秒前
新书速览|Java网络爬虫精解与实践
java·开发语言·爬虫
WaaTong3 分钟前
《重学Java设计模式》之 单例模式
java·单例模式·设计模式
面试鸭5 分钟前
离谱!买个人信息买到网安公司头上???
java·开发语言·职场和发展
沈询-阿里1 小时前
java-智能识别车牌号_基于spring ai和开源国产大模型_qwen vl
java·开发语言
AaVictory.1 小时前
Android 开发 Java中 list实现 按照时间格式 yyyy-MM-dd HH:mm 顺序
android·java·list
LuckyLay1 小时前
Spring学习笔记_27——@EnableLoadTimeWeaving
java·spring boot·spring
向阳12182 小时前
Dubbo负载均衡
java·运维·负载均衡·dubbo
Gu Gu Study2 小时前
【用Java学习数据结构系列】泛型上界与通配符上界
java·开发语言
WaaTong2 小时前
《重学Java设计模式》之 原型模式
java·设计模式·原型模式