【AgileTC】_Filter过滤器的原理与使用

【AgileTC】_Filter过滤器的原理与使用

  • 1.在启动类上添加@ServletComponentScan注解,用于扫描过滤器相关注解;

  • 2.创建一个实现Filter接口的过滤器类,该过滤器用于将cookie中的username取出并放入请求头中:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    @WebFilter
    public class InfoFilter implements Filter {

    private static final String USERNAME = "username";

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

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    RequestHeaderWrapper wrapper = new RequestHeaderWrapper(request);

    //寻找Cookie中键为username的数据,并将其添加到请求头中。
    String username = CookieUtils.getCookieValue(request,USERNAME);

    if (!StringUtils.isEmpty(username)) {
    wrapper.addHeader(USERNAME,username);
    }

    filterChain.doFilter(wrapper,servletResponse);
    }

    @Override
    public void destroy() {
    }
    }
  • 3.创建一个继承HttpServletRequestWrapper的封装类,主要用于封装request请求消息,提供添加header请求头的方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    public class RequestHeaderWrapper extends HttpServletRequestWrapper {

    public RequestHeaderWrapper(HttpServletRequest request) {
    super(request);
    }

    private Map<String, String> headerMap = new HashMap<>();

    public void addHeader(String name, String value) {
    headerMap.put(name, value);
    }

    @Override
    public String getHeader(String name) {
    String headerValue = super.getHeader(name);
    if (headerMap.containsKey(name)) {
    headerValue = headerMap.get(name);
    }
    return headerValue;
    }

    @Override
    public Enumeration<String> getHeaderNames() {
    List<String> names = Collections.list(super.getHeaderNames());
    for (String name : headerMap.keySet()) {
    names.add(name);
    }
    return Collections.enumeration(names);
    }

    @Override
    public Enumeration<String> getHeaders(String name) {
    List<String> values = Collections.list(super.getHeaders(name));
    if (headerMap.containsKey(name)) {
    values.add(headerMap.get(name));
    }
    return Collections.enumeration(values);
    }
    }
  • 创建并配置完该Filter之后,该项目中有两个Filter,但是具体先执行那个Filter我们并没有配置,tomcat自动帮我们先执行了info,后执行了shiro;实际上tomcat是使用了一个hashmap来为我们保存所有过滤器,我们可以通过打断点debug查看源码来查看容器中过滤器的存储顺序,也可在此基础之上寻找方法改变过滤器顺序,比如创建一个AppInitializer类来自定义过滤器顺序