过滤器Filter和拦截器Inteceptor的区别
过滤器Filter和拦截器Inteceptor在在tomcat容器中从里到外的顺序如下:
由上图总结过滤器和拦截器的区别:
- Filter不依赖于servlet容器,Inteceptor依赖于servlet容器。所以Filter只能在servlet前后起作用,Inteceptor可以深入sevlet中到具体方法的前后。
- Filter在Servlet规范中定义的,是Servlet容器支持的;Inteceptor是spring容器内的,是Spring框架支持的,基于SpringAOP实现的。
- Filter只能用于Web程序中,Inteceptor不限于Web程序。
过滤器Filter和拦截器Inteceptor的使用
Filter使用实例:过滤器的配置是需要写在web.xml文件中。
<filter><!--指定自定义Filter的位置-->
<filter-name>RequestFilter</filter-name>
<filter-class>com.msmk.cloud.controller.VrFilter</filter-class>
</filter>
<filter-mapping><!--定义拦截路径-->
<filter-name>RequestFilter</filter-name>
<url-pattern>/vr/*</url-pattern>
</filter-mapping>
上面配置中的VrFilter类,需要继承OncePerRequestFilter:
public class VrFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//此处写过滤器的业务逻辑
//业务逻辑执行完以后要调用doFilter,只有调用了doFilter继续按照web.xml配置的过滤器顺序继续走下一个过滤器。
filterChain.doFilter(request,response);
}
}
使用过滤器Filter的注意事项:
- 不要使用Spring的依赖注入属性到Filter,会报空指针。
- 启动顺序: context-param(例如:tomcat配置文件)->listener -> filter -> servlet
- Filter获取bean的方法。
//获取UserService类
ServletContext context = request.getServletContext();
ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(context);
UserService userService = ctx.getBean(UserService.class);
拦截器:拦截器的配置文件放在springMVC的配置文件中。mvc-servlet.xml
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/vr/**"/><!--规定拦截请求的路径-->
<bean class="com.msmk.cloud.controller.VrInterceptor"/><!--指定自定义的拦截器-->
</mvc:interceptor>
</mvc:interceptors>
VrInterceptor的实现:需要继承HandlerInterceptor
@Component
public class VrInterceptor implements HandlerInterceptor {
@Autowired
private AuthenticationManager preAuthenticationManager;
@Autowired
private UserService userService;
//请求之前执行的方法
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
return true;
}
/**
*这个方法只会在当前这个Interceptor的preHandle方法返回值为true的时候才会执行。postHandle是进行处理器拦截用的,它的执行时间是在处理器进行处理之 后,也就是在Controller的方法调用之后执行,但是它会在DispatcherServlet进行视图的渲染之前执行,也就是说在这个方法中你可以对ModelAndView进行操作。
**/
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
/**
*该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行。该方法将在整个请求完成之后,也就是DispatcherServlet渲染了视图执行,这个方法的主要作用是用于清理资源的。
**/
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}