JavaWeb Filter

本文详细介绍了JavaWeb中的Filter组件,包括其作用、基本操作(init、doFilter和destroy),以及如何配置拦截路径、执行流程和登录校验的应用。还提到了第三方工具fastjson在处理JSON数据中的应用。
摘要由CSDN通过智能技术生成

过滤器Filter

  • Filter
    • Filter表示过滤器,是 JavaWeb三大组件(Servlet、Filter、Listener)之一
    • 作用: 过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能
      • 使用了过滤器之后,要想访问web服务器上的资源,必须先经过滤器,过滤器处理完毕之后, 才可以访问对应的资源。
    • 通用操作: 登录校验、统一编码处理、敏感字符处理等在这里插入图片描述

Filter的基本使用操作

  • 定义过滤器
    • 定义一个类,实现 Filter 接口,并重写其所有方法

    • //配置过滤器要拦截的请求路径( /* 表示拦截浏览器的所有请求 )
      //@WebFilter(urlPatterns = "/*") 
      
      //定义一个类,实现一个标准的Filter过滤器的接口
      public class DemoFilter implements Filter {
          @Override //初始化方法, 只调用一次
          public void init(FilterConfig filterConfig) throws ServletException {
              System.out.println("init 初始化方法执行了");
          }
          
          @Override //拦截到请求之后调用, 调用多次
          public void doFilter(ServletRequest request, ServletResponse response, 			FilterChain chain) throws IOException, ServletException {
              System.out.println("Demo 拦截到了请求...放行前逻辑");
              //放行
              chain.doFilter(request,response);
          }
          
          @Override //销毁方法, 只调用一次
          public void destroy() {
              System.out.println("destroy 销毁方法执行了");
          }
       }
      
      • init方法:
        • 过滤器的初始化方法。在web服务器启动的时候会自动的创建Filter过滤器对象,在创建过滤器对象的时候会自动调用init初始化方法,这个方法只会被调用一次。
      • doFilter方法:
        • 这个方法是在每一次拦截到请求之后都会被调用,所以这个方法是会被调用多次的,每拦截到一次请求就会调用一次doFilter()方法。
      • destroy方法:
        • 是销毁的方法。当我们关闭服务器的时候,它会自动的调用销毁方法 destroy,而这个销毁方法也只会被调用一次。
  • 配置过滤器

    ​ 在定义完Filter之后,Filter其实并不会生效,还需要完成Filter的配置

    • Filter的配置

      • 1.Filter类上加 @WebFilter 注解,并通过属性urlPatterns配置拦截资源的路径。
      • 2.引导类上加 @ServletComponentScan 开启Servlet组件支持
    • Filter类上加 @WebFilter 注解

      //配置过滤器要拦截的请求路径( /* 表示拦截浏览器的所有请求 )
      @WebFilter(urlPatterns = "/*") 
      //定义一个类,实现一个标准的Filter过滤器的接口
      public class DemoFilter implements Filter {
          @Override //初始化方法, 只调用一次
          public void init(FilterConfig filterConfig) throws ServletException {
              System.out.println("init 初始化方法执行了");
          }
          
          @Override //拦截到请求之后调用, 调用多次
          public void doFilter(ServletRequest request, ServletResponse response, 			FilterChain chain) throws IOException, ServletException {
              System.out.println("Demo 拦截到了请求...放行前逻辑");
              //放行
              chain.doFilter(request,response);
          }
          
          @Override //销毁方法, 只调用一次
          public void destroy() {
              System.out.println("destroy 销毁方法执行了");
          }
       }
      
    • 引导类上面加上一个注解 @ServletComponentScan

      @ServletComponentScan
      @SpringBootApplication
       public class TliasWebManagementApplication {
       public static void main(String[] args) {
       	SpringApplication.run(TliasWebManagementApplication.class, args);
        }
      }
      
  • 注意事项:

    ​ 在过滤器Filter中,如果不执行放行操作,将无法访问后面的资源。

    ​ 放行操作: chain.doFilter(request, response);

Filter详解

过滤器的执行流程

在这里插入图片描述

​ 1.过滤器拦截到了请求之后,执行放行前的逻辑【调用doFilter()方法前的代码属于放行之前的逻辑】

​ 2.然后调用 FilterChain对象当中的doFilter()方法放行。

​ 3.放行后访问 web 资源

​ 4.之后回到过滤器当中,执行放行之后的逻辑【放行之后的逻辑写在doFilter()这行代码之后】

    @Override //拦截到请求之后调用, 调用多次
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain 		chain) throws IOException, ServletException {
        System.out.println("Demo 拦截到了请求...放行前逻辑");
        //放行
        chain.doFilter(request,response);
        System.out.println("Demo 拦截到了请求...放行后逻辑");      
    }

过滤器的拦截路径配置

拦截路径urlPatterns值含义
拦截具体路径/login只有访问 /login 路径时,才会被拦截
目录拦截/emps/*访问/emps下的所有资源,都会被拦截
拦截所有/*访问所有资源,都会被拦截

过滤器链

​ 过滤器链指的是在一个web应用程序当中,可 以配置多个过滤器,多个过滤器就形成了一个过滤器链。在这里插入图片描述

  • 举例说明

    ​ 在web服务器当中,定义了两个过滤器,这两个过滤器就形成了一个过滤器链。(如上图所示)

    ​ 链上的过滤器在执行的时候会一个一个的执行,会先执行第一个Filter,放行之后再来执行第二 个Filter,如果执行到了最后一个过滤器放行之后,才会访问对应的web资源

    ​ 访问完web资源之后,还会回到过滤器当中来执行过滤器放行后的逻辑,而在执行放行后的逻辑的时候,顺序是反着的。先要执行过滤器2放行之后的逻辑,再来执行过滤器1放行之后的逻辑,最后在给浏览器响应数据。

  • 过滤器链中过滤器优先级

    • 注解方式配置的Filter过滤器,它的执行优先级是按过滤器类名的自动排序确定的,类名排名越靠前,优先级越高。
    • 想要修改过滤器链中过滤器的执行顺序,可以修改类名

登录校验-Filter

  • 登录校验的基本流程:在这里插入图片描述

    • 访问登录接口login。

    • 登录成功之后,在服务端生成一个JWT令牌,并且把JWT令牌返回给前端,前端会将JWT令牌存储下来。

    • 在后续的每次请求当中,都会将JWT令牌携带到服务端,请求到达服务端之后,先要校验令牌的有效性。

      • 除了登录请求外,所有的请求,拦截到了之后,都需要校验令牌
    • 对于校验令牌使用登录校验的过滤器,在过滤器当中来校验令牌的有效性。

    • 如果令牌是无效的,就响应一个错误的信息,也不会再去放行访问对应的资源了。

    • 如果令牌存在且有效,此时就会放行去访问对应的web资源,执行相应的业务操作。

  • 具体流程【利用Filter过滤器】在这里插入图片描述

  • 代码实现
    • 第三方json处理的工具包fastjson

      • fastjson是阿里巴巴提供的,用于实现对象和json的转换工具类

        //将对象转换成json格式的字符串
        String json=JSONObject.toJSONString(对象);
        
      • 使用时 需要引入如下依赖

         <dependency>
         	<groupId>com.alibaba</groupId>
         	<artifactId>fastjson</artifactId>
         	<version>1.2.76</version>
         </dependency>
        
    • 登录校验过滤器:LoginCheckFilter

      @Slf4j
      @WebFilter(urlPatterns = "/*") //拦截所有请求
      public class LoginCheckFilter implements Filter {
      	@Override
       	public void doFilter(ServletRequest servletRequest, ServletResponse 			servletResponse, FilterChain chain) throws IOException, ServletException {
       		//前置:强制转换为http协议的请求对象、响应对象 (转换原因:要使用子类中特有方法)
      		HttpServletRequest request = (HttpServletRequest) servletRequest;
              HttpServletResponse response = (HttpServletResponse) servletResponse;
       
              //1.获取请求url
       		String url = request.getRequestURL().toString();
       		log.info("请求路径:{}", url); //请求路径:http://localhost:8080/login
              
        		//2.判断请求url中是否包含login,如果包含,说明是登录操作,放行
              if(url.contains("/login")){
                  chain.doFilter(request, response);//放行请求
                  return;//结束当前方法的执行
              }
              
              //3.获取请求头中的令牌(token)
              String token = request.getHeader("token");
              log.info("从请求头中获取的令牌:{}",token);
              
              //4.判断令牌是否存在,如果不存在,返回错误结果(未登录)
              if(!StringUtils.hasLength(token)){
                  log.info("Token不存在");
                  Result responseResult = Result.error("NOT_LOGIN");
                  //把Result对象转换为JSON格式字符串
                  String json = JSONObject.toJSONString(responseResult);
                  response.setContentType("application/json;charset=utf8");
                  //响应
                  response.getWriter().write(json);
                  return;
              }
              
              //5.解析token,如果解析失败,返回错误结果(未登录)
              try {
                  JwtUtils.parseJWT(token);
              }catch (Exception e){
                  log.info("令牌解析失败!");
                  Result responseResult = Result.error("NOT_LOGIN");
                  //把Result对象转换为JSON格式字符串
                  String json = JSONObject.toJSONString(responseResult);
                  response.setContentType("application/json;charset=utf8");
                  //响应
                  response.getWriter().write(json);
                  return;
                  }
       
              //6.放行
      		chain.doFilter(request, response);
        }
       }
      
  • 20
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值