赞
踩
我们这里先上代码,看看拦截器和过滤器在代码实现上的区别。
1、定义一个类,实现接口Filter
public class FilterDemo implements Filter {
}
2、实现Filter
接口的方法
public class FilterDemo implements Filter { public static int i = 0; @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("执行init方法"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("执行doFilter方法 + " + i++); filterChain.doFilter(servletRequest,servletResponse); } @Override public void destroy() { System.out.println("执行destroy方法"); } }
3、配置拦截路径
1)通过web.xml文件配置
<filter>
<filter-name>FilterDemo</filter-name>
<filter-class>com.example.springboot_demo.filter.FilterDemo</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterDemo</filter-name>
<!-- 拦截路径 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
2)、注解
@WebFilter("/*")
1、定义一个类实现HandlerInterceptor
并实现此接口的方法
public class InterceptorDemo implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("执行preHandle方法"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("执行postHandle方法"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("执行afterCompletion方法"); } }
2、创建一个配置类,实现WebMvcConfigurer
@Configuration
public class MyConfig implements WebMvcConfigurer {
}
3、实现WebMvcConfigurer
的addInterceptors
方法
@Configuration
public class MyConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
}
}
4、将自定义的拦截器进行注册,并配置拦截路径和放行路径
@Configuration
public class MyConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册自定义的拦截器
InterceptorRegistration interceptorRegistration = registry.addInterceptor(new InterceptorDemo());
// 定义拦截所有路径
interceptorRegistration.addPathPatterns("/**");
// 定义排查/user/下的所有路径
interceptorRegistration.excludePathPatterns("/user/**");
}
}
这就是过滤器和拦截器的代码实现,展示了它们在代码层面的不同。后面将会进行详细解释。
过滤器是Servlet的高级特性之一,就是Web服务器在处理请求的时候会经过每一过滤器再处理请求。
自定义拦截器其实就是实现Filter
接口,然后实现他的方法。
那它的方法都有什么作用呢?
1)init方法
public void init(FilterConfig filterConfig)
2)doFilter方法
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
filterChain.doFilter(servletRequest, servletResponse);
来调用下一个过滤器,否则这个请求就到此结束了。3)destroy方法
public void destroy()
public class FilterDemo implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("执行init方法"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("执行doFilter方法"); filterChain.doFilter(servletRequest,servletResponse); } @Override public void destroy() { System.out.println("执行destroy方法"); } }
1)通过web.xml文件配置
<filter>
<filter-name>FilterDemo</filter-name>
<filter-class>com.example.springboot_demo.filter.FilterDemo</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterDemo</filter-name>
<!-- 拦截路径 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
2)、注解
@WebFilter(filterName = "FilterDemo",urlPatterns = "/*")
过滤器执行主要是通过函数回调的方式。
在我们自定义的过滤器中都会实现一个 doFilter()方法,这个方法有一个FilterChain 参数,而实际上它是一个回调接口。
所以,如果我们写这样的过滤器
public class FilterDemo implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("执行init方法"); } @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { System.out.println("准备放行"); //执行这一句,说明放行(让下一个过滤器执行,或者执行目标资源) chain.doFilter(req, resp); System.out.println("放行完成"); } @Override public void destroy() { System.out.println("执行destroy方法"); } }
程序在执行到chain.doFilter(req,resp)
时会执行下一个过滤器或目标资源,然后执行完成回到此方法继续往下执行。
过滤器之间的执行顺序看在web.xml文件中mapping的先后顺序的,如果放在前面就先执行,放在后面就后执行!
如果是通过注解的方式配置,就比较urlPatterns的字符串优先级
拦截器是SpringMVC自己的功能,虽然看起来和过滤器一样,但是底层使用的是面向切面编程AOP。
前面我们直到自定义拦截器要实现HandlerInterceptor
接口,然后再实现它的方法。
那这几个方法都有什么作用呢?
1)preHandle方法
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler);
2)postHandle方法
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView);
3)afterCompletion方法
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex);
public class InterceptorDemo implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("执行preHandle方法"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("执行postHandle方法"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("执行afterCompletion方法"); } }
创建一个实现WebMvcConfigurer
的拦截器,然后将自定义的拦截器注册到其中。可以注册多个拦截器。
实现方法addInterceptors
,通过参数InterceptorRegistry registry
来进行一系列配置
@Configuration
public class MyConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册自定义的拦截器
InterceptorRegistration interceptorRegistration = registry.addInterceptor(new InterceptorDemo());
// 定义拦截所有路径
interceptorRegistration.addPathPatterns("/**");
// 定义排查/user/下的所有路径
interceptorRegistration.excludePathPatterns("/user/**");
// 确定执行顺序
interceptorRegistration.order(1);
}
}
InterceptorRegistration interceptorRegistration = registry.addInterceptor(new InterceptorDemo());
将自定义的拦截器对象传入其中即可,如果要注册多个拦截器,调用多次这个方法即可。
interceptorRegistration.addPathPatterns("/**");
如果需要拦截多个路径,可以多次传入一个字符串,也可以传入一个List集合。
interceptorRegistration.excludePathPatterns("/user/**");
这个和addPathPatterns
一样,可以传入字符串,也可以传入List
多个拦截器可通过
order()
方法来确定执行顺序,order()
传入一个数字,数字越小则越先执行。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。