过滤器介绍

过滤器是AOP思想的具体体现,仅对请求加工两次(访问controller前,访问controller后)。过滤器可以过滤浏览器发出的强求,并且决定放行请求还是中断请求。

此外,基于过滤器的机制,我们可以做以下功能:校验请求的敏感字符串、校验有无sessison、实现url级别的权限控制等。

过滤器实现

我们定义一个过滤器,该过滤器不完成任何功能,仅仅记录每一笔交易的耗时。

定义过滤器类

首先,我们需要定义一个过滤器类,实现Filter类的功能。比如:

@Slf4j
@Component
public class RuntimeRecordFilter implements Filter {

    /**
     * 完成filter的初始化
     * @param filterConfig
     * @throws ServletException
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    /**
     * 实现过滤功能,对每个请求及响应增加额外的预处理跟后处理。需要调用doFilter,否则用户的请求无法被处理
     * @param request
     * @param response
     * @param chain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        long now = System.currentTimeMillis();
        String requestURI = ((HttpServletRequest) request).getRequestURI();
        try {
            chain.doFilter(request, response);
        }finally {
            // 输出每一笔交易的耗时
            log.info("requestUrl: {}, responseTime: {}ms", requestURI, System.currentTimeMillis()-now);
        }
    }
}

在doFilter函数中,我们会记录每一笔交易的开始时间、结束时间,来记录交易耗时功能,并通过日志打印功能进行输出。 此外,chain.doFilter(request, response)则是容器中每一次请求都会调用该方法,从而实现过滤效果。在doFilter方法中,chain.doFilter()前是对request执行的过滤操作,chain.doFilter()后是对response的执行操作

配置过滤器类

定义完过滤器后,我们可以通过配置从而使用过滤器。具体地,我们可以手写一个由@Configuration注解的配置类。具体如下:

@Configuration
public class FilterConfig {

    @Autowired
    RuntimeRecordFilter runtimeRecordFilter;

    @Bean
    public FilterRegistrationBean registrationRuntimRecordFilterBean(){
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(runtimeRecordFilter);
        // /* 表示对所有的路径都进行过滤
        registrationBean.addUrlPatterns("/*");
        registrationBean.setName(RuntimeRecordFilter.class.getName());
        // order越小,优先级越高
        registrationBean.setOrder(5);
        return registrationBean;
    }
}

该代码块涉及到的注解:

  • @Configuration:声明一个类作为配置类,代替XML文件。
  • @Bean注解:声明在方法上,将方法的返回值加入Bean容器,从而代替标签。

其中,addUrlPatterns则是对过滤器的使用范围进行限定,而"/*"则是对所有的请求路径都能产生效果。setOrder则是定义该过滤器的优先级,并且order值越小,优先级越高。

使用后,效果如下:

alt