过滤器介绍
过滤器是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值越小,优先级越高。
使用后,效果如下: