五十、Filter過濾器,Interceptor攔截器,ControllerAdvice,Aspect切片
阿新 • • 發佈:2018-12-28
Filter過濾器,Interceptor攔截器,ControllerAdvice,Aspect切片
上圖為在web專案中,在處理request請求時得處理順序
在專案中我們改怎麼使用呢?
Filter過濾器
/** * Created by GAOMINGQIAN on 2017/12/10. *<pr> * Filter只能獲取到請求的request和response。獲取不到其他的資訊 * 因為Filter屬於J2EE的內容,不知道spring * 會攔截所有的請求 *</pr> * */ //@Component public class TimeFilter implements Filter { //初始化的時候呼叫 @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("time filter init"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("time filter start"); long start=new Date().getTime(); filterChain.doFilter(servletRequest,servletResponse); System.out.println("time filter end:"+(new Date().getTime()-start)); System.out.println("time filter finsh"); } //銷燬時呼叫 @Override public void destroy() { System.out.println("time filter destory"); } }
上述內容中有一個@Component註解,當我們不想使用時或者更細的粒度攔截,需要在config類中進行註冊
//配置一個過濾器 @Bean public FilterRegistrationBean timeFilter() { //filter註冊用的bean FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); TimeFilter timeFilter = new TimeFilter(); filterRegistrationBean.setFilter(timeFilter); List<String> urls = new ArrayList<>(); urls.add("/*"); //設定filter對那些請求有作用,這裡設定的是對所有的請求都有作用 filterRegistrationBean.setUrlPatterns(urls); return filterRegistrationBean; }
Interceptor攔截器
/** * Created by GAOMINGQIAN on 2017/12/10. */ public class TimeInterceptor implements HandlerInterceptor { //該方法的返回值決定後續的方法是否執行(controller中的方法) @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { System.out.println("preHandle"); //獲取controller類名稱 System.out.println(((HandlerMethod) o).getBean().getClass().getName()); //獲取執行method的名字 System.out.println(((HandlerMethod)o).getMethod().getName()); httpServletRequest.setAttribute("startTime", new Date().getTime()); return true; } //當controller丟擲異常時,該方法不會被呼叫 @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { System.out.println("postHandle"); long start = (Long) httpServletRequest.getAttribute("startTime"); System.out.println("time interceptor耗時" + (new Date().getTime() - start)); } @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { System.out.println("afterCompletion"); long start = (Long) httpServletRequest.getAttribute("startTime"); System.out.println("time interceptor耗時" + (new Date().getTime() - start)); //當無異常的時候,e的值為null,有自定義異常時,也會為Null System.out.println(e); } }
需要在配置類中宣告才能使用,繼承WebMvcConfigurerAdapter
//告訴spring這是一個配置類 @Configuration public class WebConfig extends WebMvcConfigurerAdapter{ @Override public void addInterceptors(InterceptorRegistry registry) { //註冊當前的攔截器 registry.addInterceptor(new TimeInterceptor()); } }
Aspect切片使用
/** * Created by GAOMINGQIAN on 2017/12/10. */ @Aspect @Component public class TimeAspect { //around中的execution中的內容代表對哪些方法進行攔截 @Around("execution(* study.security.web.controller.UserController.*(..))") public Object handlerControllerMethod(ProceedingJoinPoint pjp) throws Throwable { System.out.println("time aspect start"); //獲取執行方法的引數 Object[] args = pjp.getArgs(); long start = new Date().getTime(); //執行攔截的方法 result為攔截方法的返回值 Object result = pjp.proceed(); System.out.println("time aspect 耗時:" + (new Date().getTime() - start)); return result; } }
ControllerAdvice,主要用於異常處理的控制器
/** * Created by GAOMINGQIAN on 2017/12/10. */ @ControllerAdvice public class ControllerHandlerException { @ExceptionHandler(UserNotExistException.class) @ResponseBody @ResponseStatus(HttpStatus.BAD_REQUEST) public Map<String, Object> handleUserNotExistException(UserNotExistException ex) { Map<String, Object> result = new HashedMap(); //放置需要響應的內容 result.put("message",ex.getMessage()); return result; } }
優缺點介紹:
Filter過濾器:可以拿到request,response但是拿不到處理方法的資訊
Interceptor攔截器:可以拿到request,response,也可以拿到處理方法的資訊,但是拿不到處理方法引數的值
Aspect切片:可以拿到處理方法的所有資訊,但是拿不到request,response