本文仅讲述过滤器,拦截器文章链接在本文最下方。

什么是Filter

可以拦截所有的请求与响应。

过滤器Filter 生命周期

它是随你的web应用启动而启动的,只初始化一次,以后就可以拦截相关请求,只有当你的web应用停止或重新部署的时候才销毁。

使用过滤器Filter完整的流程是

过滤器Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。

Tomcat容器结构

我们看一下 Tomcat容器结构:

过滤器Filter 在 拦截器Interceptor前面。就可以得知一个请求从Filter到Servlet、Interceptor、Controller。这里也就是全局异常处理类(只能处理Controller层的异常)无法处理Filter报错的原因!

什么场景 会使用 Filter?

  • 请求日志:比如 张三 XX时间 访问了 什么什么接口 等待
  • 用户授权:负责检查用户请求,根据请求过滤用户非法请求。
  • 非标准编码的请求解码:可以解决 一些字符集啊 之类的问题,(早期Servlet与Tomcat的问题)

多个过滤器或拦截器的执行顺序

一个请求或响应可以被多个自定义过滤器Filter过滤或拦截器拦截,控制其加载顺序,一般是类上加注解 @Order(数值越小,拦截执行优先级越大)

执行的优先级是按照过滤器类名(字符串)的自然排序,如Axx与Bxx,那么肯定是Axx先执行

如何使用Filter?

实现javax.servlet.Filter 接口,重写其 init()、destory()、doDilter()方法

1、在启动类上开启 @ServletComponentScan

@ServletComponentScan

2、在config 层 写一个 配置类

import lombok.extern.slf4j.Slf4j;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;

/**
 * 作者:臧立昆
 * 2020/10/16 13:11
 */
@Slf4j
@WebFilter(filterName = "myFilter", urlPatterns = "/*")
public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) {
        //log.info(filterConfig.getFilterName() + " init");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        try {
            //TODO 接口放行,如果不想让接口放行,让代码不执行本行即可!
            chain.doFilter(request, response);
        } catch (Exception e) {
            //log.error("error!", e);
        }
        //log.info("过滤器 end");
    }

    @Override
    public void destroy() {
    }
}

过滤器相关代码基本完成!

过滤器限制Token 伪代码,可直接用!

import lombok.extern.slf4j.Slf4j;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * 作者:臧立昆
 * 2020/10/16 13:11
 */
@Slf4j
@WebFilter(filterName = "myFilter", urlPatterns = "/*")
@Order(-1) // 加载优先级 数字越小
public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) {
        //log.info(filterConfig.getFilterName() + " init");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {

        try {
            //todo 将servlet的request转为 HttpServletRequest,方便我们快速获取:前端请求的内容:请求头、请求体。
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            String token = httpServletRequest.getHeader("token");
            //todo 我们校验相关的token,如JWT校验一下,在决定是否放行接口!        
            if (Please check Request,if you want to filter!) {
                chain.doFilter(request, response);
            } else {
                log.error("Token 无效,请输入有效Token");
            }

        } catch (Exception e) {
            log.error("过滤器过滤Token 出现异常,可能是Token无效导致的异常!");
        }

    }

    @Override
    public void destroy() {
    }
}

如果不想用@Order指定过滤器加载优先级,可以过滤器实现Order接口,重写value方法

import org.springframework.core.annotation.Order;


    // 重写value()方法,自己指定设定Order数字级别 -1最优先
    @Override
    public int value() {
        return -1;
    }

想要了解interceptor拦截器,请跳转本站其他链接查看

特殊说明:
上述文章均是作者实际操作后产出。烦请各位,请勿直接盗用!转载记得标注原文链接:www.zanglikun.com
第三方平台不会及时更新本文最新内容。如果发现本文资料不全,可访问本人的Java博客搜索:标题关键字。以获取全部资料 ❤