一、什么是过滤器,拦截器
过滤器(Filter)
过滤器,是在java web中将你传入的request、response提前过滤掉一些信息,或者提前设置一些参数。然后再传入Servle进行业务逻辑处理。比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入Servlet前统一设置字符集,或者去除掉一些非法字符。
拦截器(Interceptor)
拦截器,是面向切面编程(AOP,Aspect Oriented Program)的。就是在你的Service或者一个方法前调用一个方法,或者在方法后调用一个方法。比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。
二、拦截器与过滤器的区别
1、拦截器是基于java的反射机制的,而过滤器是基于函数的回调。
2、拦截器不依赖于servlet容器,而过滤器依赖于servlet容器。
3、拦截器只对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
4、拦截器可以访问action上下文、值、栈里面的对象,而过滤器不可以。
5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
6、拦截器可以获取IOC容器中的各个bean,而过滤器不行,在拦截器里注入一个service,可以调用业务逻辑。
三、拦截器与过滤器的触发时机
1、过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的
2、拦截器是在servlet处理完后,返回给前端之前。
3、过滤器包裹servlet,servlet包裹住拦截器
四、定义过滤器
实现filter接口
@WebFilter(filterName = "AFilter",urlPatterns = "/*")
public class AFilter implements Filter {
public void destroy() {
System.out.println("AFilter destroy");
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("Before doFilter");
chain.doFilter(req, resp);
System.out.println("After doFilter");
}
public void init(FilterConfig config) throws ServletException {
System.out.println("AFilter init ·····");
}
}
FilterConfig配置类
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<AFilter> filterRegister() {
FilterRegistrationBean<AFilter> filterRegistrationBean = new FilterRegistrationBean<>();
filterRegistrationBean.setFilter(new AFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.setName("AFilter");
filterRegistrationBean.setOrder(1);
return filterRegistrationBean;
}
}
五、定义拦截器
LoginInterceptor登陆拦截器 判断是否登陆
public class LoginInterceptor implements HandlerInterceptor {
public LoginInterceptor(){
System.out.println("L拦截器创建了");
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle`````````");
String uri = request.getRequestURI();
String idStr = request.getParameter("id");
if (idStr != null) {
Integer id = Integer.parseInt(idStr);
User user = new User();
user.setId(id);
request.getSession().setAttribute("user", user);
}
User user = (User)request.getSession().getAttribute("user");
if (uri.contains("login")) {
return true;
}
if (user != null) {
return true;
}
response.sendRedirect("login.html");
return false;
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("拦截器拦截完成");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
InterceptorConfig 配置类
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**")
.excludePathPatterns("/","/html/**","/css/**","/images/**","/*.html","/js/**");
}
}
总结:
拦截器的应用场景:权限控制,日志打印,参数校验。
过滤器的应用场景:跨域问题解决,编码转换。