过滤器(filter)简介

  • 过滤器是Javaweb的组件之一,用来过滤请求和处理响应

过滤器实际上就是对web资源进行拦截,做一些处理后再交给下一个过滤器或servlet处理
通常都是用来拦截request进行处理的,也可以对返回的response进行拦截处理

使用场景

1.设置请求/响应字符编码

2.校验登录权限

3.敏感词汇的过滤

大致流程图如下:

java 认证过滤器 java的过滤器_html

filter的使用(xml配置)

1,声明一个过滤器类要实现Filter接口(CusFilter类)

public class CusFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("filter 初始化了");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        /*过滤方法 主要是对request和response进行一些处理,然后交给下一个过滤器或Servlet处理*/
        System.out.println("过滤请求了!!!");
        //给请求放行 请求真正的资源/或者到下一个过滤器
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        System.out.println("filter 销毁了");
    }
}

2、配置 web.xml 文件

<filter>
    <filter-name>filter</filter-name>
    <filter-class>com.codeyancy.filter.CusFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>filter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

过滤器(Filter)的生命周期

构造 —> 初始化 —> 过滤 —> 销毁

  • 构造和初始化是在应用部署好后就执行的而不是第一次访问,而且是只执行一次
  • 过滤方法是每次指定的请求发送过来的时候执行
  • 销毁方法是应用卸载或者TOMCAT关闭的时候执行

过滤器(Filter)的拦截路径写法

<filter-mapping>
        <filter-name>filter</filter-name>
        <!--       /* 表示过滤所有请求  -->
        <url-pattern>/*</url-pattern>
        <!--精确路径过滤-->
        <url-pattern>/ajaSearch.html</url-pattern>
        <!--后缀名匹配过滤-->
        <url-pattern>*.html</url-pattern>
        <!--目录匹配过滤-->
        <url-pattern>/html/*</url-pattern>
    </filter-mapping>

filter的使用(注解形式)

使用注解形式,就不需要再配置web.xml了

只需要在实现Filter接口的类上添加注解@WebFilter("/*")即可

@WebFilter("/*")
public class CusFilter implements Filter {

多个过滤器(Filter)的执行顺序

在请求到达Servle之间是可以经过多个过滤器(Filter)的,一般情况下,建议过滤器(Filter)之间不要有关联,各自处理各自的逻辑即可。这样,我们也不需要关心执行顺序问题。

如果一定要确保执行顺序,就要对配置进行修改了,多个过滤器(Filter)的执行顺序如下

  • 使用web.xml 配置,filter执行顺序跟的顺序有关,先声明的就会先执行
  • 使用注解配置,filter的执行顺序跟filter名称的字母顺序有关,例如AFilter会比BFilter先执行
  • 如果既有在web.xml中声明的Filter,也有通过注解配置的Filter,那么会优先执行web.xml中配置的Filter

FilterConfig配置类

每个filter都有一个配置类

@Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //获取filter的初始化参数
        String jdbcUrl = filterConfig.getInitParameter("jdbcUrl");
        System.out.println(jdbcUrl);
        // 获取上下文对象
        ServletContext servletContext = filterConfig.getServletContext();
        System.out.println("filter 初始化了");
    }

web.xml文件配置初始化参数

<filter>
    <filter-name>filter</filter-name>
    <filter-class>com.codeyancy.filter.CusFilter</filter-class>
    <init-param>
      <param-name>jdbcUrl</param-name>
      <param-value>dbc:mysql://192.168.0.1:3306/</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>filter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

使用过滤器处理请求响应乱码案例

主要代码演示:

@Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //处理乱码
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/json;charset=UTF-8");

        String requestURI = request.getRequestURI();
        //System.out.println("filter1 拦截了请求..." + requestURI);
        filterChain.doFilter(servletRequest, servletResponse);
        //System.out.println("filter1 响应了请求...");
    }

使用过滤器进行校验登陆权限案例

1.前端login.html

<body>
<form action="/auth">
    user <input type="text" name="username"> <br>
    pass <input type="password" name="password"> <br>
    <input type="submit" value="登录">
</form>
</body>

2.后端权限校验servlet(AuthController 类)

@WebServlet("/auth")
public class AuthController extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if("tom".equals(username)&&"666".equals(password)){
            //验证成功后往session域中存放登录信息
            HttpSession session = req.getSession();
            session.setAttribute("user",new User(username,password));

            resp.sendRedirect("/index.html");
        }else {
            resp.sendRedirect("/login.html");
        }
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

3.后端过滤器(CusFilter2类)

@WebFilter("/*")
public class CusFilter2 implements Filter {
    public CusFilter2() {
        System.out.println("filter2 过滤器构造了");
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("filter2 初始化");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String requestURI = request.getRequestURI();
        //不拦截 .css .js login.html index.html .img .jpg /auth
        //使用正则表达式
        Pattern compile = Pattern.compile(".*(css|js|login.html|index.html|img|jpg|auth)$");
        Matcher matcher = compile.matcher(requestURI);
        if(matcher.matches()){
            //放行
            filterChain.doFilter(servletRequest,servletResponse);
        }else {
            HttpSession session = request.getSession();
            Object user = session.getAttribute("user");
            if(user==null){
                response.sendRedirect("/login.html");
            }else {
                //放行,请求真正的资源/到下一个过滤器
                filterChain.doFilter(servletRequest, servletResponse);
            }
        }
    }

    @Override
    public void destroy() {
    }
}