在springboot中使用rest服务时,往往需要对controller层的请求进行拦截或者获取请求数据和返回数据,就需要过滤器、拦截器或者切片。
过滤器(Filter):对HttpServletRequest处理,也可以对HttpServletResponse 进行后处理,无法获取请求方法的信息。
拦截器(Interceptor):可以获取HttpServletRequest、HttpServletResponse的数据,也可以获取请求方法的信息,但是无法获取请求的参数和返回参数。
切片(Aspect):aop的切片可以获取请求的参数和返回的值,但是无法获取HttpServletRequest、HttpServletResponse的数据。
- 过滤器(Filter):
@Component public class TimeFilter implements Filter { //销毁时 @Override public void destroy() { System.out.println("time filter destroy"); } //逻辑代码 @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("time filter start"); long start = new Date().getTime(); chain.doFilter(request, response); System.out.println("time filter 耗时:"+ (new Date().getTime() - start)); System.out.println("time filter finish"); } //加载前 @Override public void init(FilterConfig arg0) throws ServletException { System.out.println("time filter init"); } }
这样所有请求都能获取,如果过滤器没法加@Component定义为组件引用,可以在配置文件中引用
@Configuration public class WebConfig extends WebMvcConfigurerAdapter { @Bean public FilterRegistrationBean timeFilter() { FilterRegistrationBean registrationBean = new FilterRegistrationBean(); TimeFilter timeFilter = new TimeFilter(); registrationBean.setFilter(timeFilter); List<String> urls = new ArrayList<>(); urls.add("/*");//获取所有请求 registrationBean.setUrlPatterns(urls); return registrationBean; } }
- 拦截器(Interceptor)
@Component public class TimeInterceptor implements HandlerInterceptor { // 在业务处理器处理请求之前被调用 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle"); System.out.println(((HandlerMethod)handler).getBean().getClass().getName()); System.out.println(((HandlerMethod)handler).getMethod().getName()); request.setAttribute("startTime", new Date().getTime()); return true; } // 在业务处理器处理请求完成之后,生成视图之前执行 @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle"); Long start = (Long) request.getAttribute("startTime"); System.out.println("time interceptor 耗时:"+ (new Date().getTime() - start)); } //请求完成之后 @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion"); Long start = (Long) request.getAttribute("startTime"); System.out.println("time interceptor 耗时:"+ (new Date().getTime() - start)); System.out.println("ex is "+ex); } }
创建组件后需要在配置文件中定义下
@Configuration public class WebConfig extends WebMvcConfigurerAdapter { @SuppressWarnings("unused") @Autowired private TimeInterceptor timeInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(timeInterceptor); } }
- 切片(Aspect)
@Aspect @Component public class TimeAspect { @Around("execution(* com.project.web.controller.UserController.*(..))") public Object handleControllerMethod(ProceedingJoinPoint pjp) throws Throwable { System.out.println("time aspect start"); Object[] args = pjp.getArgs(); for (Object arg : args) { System.out.println("arg is "+arg);//获取请求参数 } long start = new Date().getTime(); Object object = pjp.proceed();//获取返回值 System.out.println("time aspect 耗时:"+ (new Date().getTime() - start)); System.out.println("time aspect end"); return object; } }
- 过滤器(Filter):
一个请求的处理顺序是过滤器(Filter)->拦截器(Interceptor)->切片(Aspect)