在开发时,免不了要对请求做拦截,基于SpringMVC的JavaWeb程序有以下一些常用的拦截方式。
0x01:J2EE的Filter拦截
J2EE结合SpirngMVC使用Filter进行请求拦截主要以下三种使用方式
@ServletComponentScan + @WebFilter
使用该方式进行拦截时,可配置过滤的路径, 但没有顺序(顺序是由过滤器命名决定)
在SpringBoot启动类上使用 @ServletComponentScan,然后再过滤器类上使用 @WebFilter(urlPatterns = {"/path"})
@SpringBootApplication@ServletComponentScanpublic class ServicemapServicecenterBackendApplication {public static void main(String[] args) {
SpringApplication.run(ServicemapServicecenterBackendApplication.class, args);
}
}
过滤器
@WebFilter(urlPatterns = {"/path"})public class UserLoinFilter extends OncePerRequestFilter {@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
System.out.println("*********** UserLoinFilter *********** ");
filterChain.doFilter(request, response);
}
}
@Component + @Order(100)
不可配置过滤的路径, 但是可以通过@Order注解来配置Filter的拦截顺序;在过滤器类上使用 @Component , @Order(100) 数值越小优先级越高
@Component@Order(100)public class UserLoginFilter extends OncePerRequestFilter {@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
System.out.println("*********** UserLoginFilter*************");
filterChain.doFilter(request, response);
}
}
@SpringBootConfiguration + @Order (推荐方式)
可配置过滤的路径, 同时可以通过@Order注解配置顺序, 另外可以在代码中使用setOrder(100)方法配置顺序
@Order(100)public class UserLoginFilter extends OncePerRequestFilter {@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
System.out.println("********* UserLoginFilter *************");
filterChain.doFilter(request, response);
}
}
配置过滤器
@SpringBootConfigurationpublic class FilterConfig {@Beanpublic FilterRegistrationBean filterOneRegister() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new UserLoginFilter());
filterRegistrationBean.addUrlPatterns("/*");// filterRegistrationBean.setOrder(100);return filterRegistrationBean;
}
}
0x02:通过基于AOP的Aspect切面拦截
Advice(通知、切面):某个连接点所采用的处理逻辑,也就是向连接点注入的代码, AOP在特定的切入点上执行的增强处理。
@Before:标识一个前置增强方法,相当于BeforeAdvice的功能
@After:final增强,不管是抛出异常或者正常退出都会执行
@AfterReturning: 后置增强,似于AfterReturningAdvice, 方法正常退出时执行
@AfterThrowing: 异常抛出增强,相当于ThrowsAdvice
@Around:环绕增强,相当于MethodInterceptor
@Aspect@Order(100)@Componentpublic class ReqestAspect {@Pointcut(value = "@annotation(org.springframework.web.bind.annotation.RequestMapping )||@annotation(org.springframework.web.bind.annotation.PutMapping)")private void pointcut(){} @After("pointcut()")public void after(JoinPoint joinPoint){//拦截
}@Before("pointcut()")public void before(JoinPoint joinPoint){//拦截
}@Around("pointcut()")public Object around(ProceedingJoinPoint joinPoint) throws Throwable {try {
Object result = joinPoint.proceed();return result ;
}catch(Exception e){throw e;
}
}
0x03:通过Interceptor 拦截
Spring 中主要通过 HandlerInterceptor 接口来实现请求的拦截,实现 HandlerInterceptor 接口需要实现下面三个方法:
preHandle():在handler执行之前,返回 boolean 值,true 表示继续执行,false 为停止执行并返回。
postHandle(): 在handler执行之后,可以在返回之前对返回的结果进行修改
afterCompletion():在请求完全结束后调用,可以用来统计请求耗时等等
public class RequestInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
System.out.println("RequestInterceptor.preHandle");return true;
}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, @Nullable ModelAndView modelAndView) throws Exception {
System.out.println("RequestInterceptor.postHandle");
}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, @Nullable Exception ex) throws Exception {
System.out.println("RequestInterceptor.afterCompletion");
}
}
![39ab0357acbdc6b01ea0060223b06448.png](https://i-blog.csdnimg.cn/blog_migrate/70c2a9785291b4b8763a8a4838195736.png)
你点的在看,我都当成了喜欢