JAVAWEB三剑客之Filter

Filter是什么

什么是Filter,看名字就是过滤器的意思,主要是针对用户发起的请求进行拦截预处理,常见的Filter应用有检查当前请求是否登录,记录请求日志,设置上下文信息等等,当然Filter也可以对请求的响应做处理,Filter的设计是个典型的责任链模式

在这里插入图片描述

  • 客户端发起http请求
  • web容器接受到请求后,调用拦截器链,依次调用各个Filter
  • 每个Filter执行完自己的逻辑后,显式调用chain.doFilter,进行下个Filter的执行,最终调用到目标servlet
  • 返回servlet数据到客户端

如何实现一个Filter

Filter的实现和之前Servlet类似,这里我们就只讲基于注解的方式来配置Filter

在上一篇的项目里,新建一个DemoFilter

  • 实现Filter接口,可实现三个方法init,doFilter destroy
  • 添加WebFilter注解,其中urlPatterns表示当前Filter需要拦截匹配的url , 这里我们配置/*表示拦截所有请求
@WebFilter(filterName = "demoFilter",urlPatterns = "/*")
public class DemoFilter implements Filter {

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

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("do filter");
        filterChain.doFilter(servletRequest,servletResponse);
    }

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

在这里插入图片描述

应用在启动时会调用filter的init方法,需要特别注意的是,在每个filter的实现里需要显式调用chain.doFilter方法,否则会导致当前请求无法触达到最终的Servlet实现

每当发起一个HTTP请求,就会匹配filter的urlPattern,如果匹配上则进入filter的doFilter方法,多个filter的顺序调用需要显式的调用chain.doFilter方法

责任链模式

Filter主要是责任链模式的实现,模拟实现拦截器实现

抽象处理类

public abstract class Filter {
    //顺序
    protected Long order;

    public Long getOrder() {
        return order;
    }

    public void setOrder(Long order) {
        this.order = order;
    }
    //核心处理方法
    abstract boolean doFilter();
}

实际处理类

public class AuthFilter extends Filter{

    public AuthFilter(Long order) {
        super.order=order;
    }

    @Override
    boolean doFilter() {
        System.out.println("AuthFilter");
        return true;
    }
}


public class LogFilter extends Filter{

    public LogFilter(Long order) {
        super.order=order;
    }

    @Override
    boolean doFilter() {
        System.out.println("LogFilter");
        return true;
    }
}

责任链类

public class FilterChain {

    List<Filter> filterList = new LinkedList<>();

    public void doFilter(){
        List<Filter> collect = filterList.stream().sorted(Comparator.comparing(Filter::getOrder)).collect(Collectors.toList());
        for (Filter filter : collect) {
            if(!filter.doFilter()){
                break;
            }
        }
    }

    public boolean add(Filter filter){
        return filterList.add(filter);
    }
}

测试链路

public class FilterTest {

    public static void main(String[] args) {
        AuthFilter authFilter = new AuthFilter(1L);
        LogFilter logFilter = new LogFilter(2L);
        FilterChain chain =new FilterChain();
        chain.add(authFilter);
        chain.add(logFilter);
        chain.doFilter();
    }
}
发布了5 篇原创文章 · 获赞 7 · 访问量 381

猜你喜欢

转载自blog.csdn.net/weixin_43593829/article/details/105604809
今日推荐