實現HandlerInterceptor介面或者繼承HandlerInterceptor的子類,比如Spring 已經提供的實現了HandlerInterceptor 介面的抽象類HandlerInterceptorAdapter ,下麵講實現其介面的寫法,先看一下這個介面的三個方法. - 方法pr ...
實現HandlerInterceptor介面或者繼承HandlerInterceptor的子類,比如Spring 已經提供的實現了HandlerInterceptor 介面的抽象類HandlerInterceptorAdapter ,下麵講實現其介面的寫法,先看一下這個介面的三個方法.
- 方法preHandle: 顧名思義,該方法將在請求處理之前進行調用,在controller之前執行。SpringMVC 中的Interceptor 是鏈式的調用的,在一個應用中或者說是在一個請求中可以同時存在多個Interceptor 。每個Interceptor 的調用會依據它的聲明順序依次執行,而且最先執行的都是Interceptor 中的preHandle 方法,所以可以在這個方法中進行一些前置初始化操作或者是對當前請求的一個預處理,比如說獲取cookie的值或者判斷是否已經登錄,也可以在這個方法中進行一些判斷來決定請求是否要繼續進行下去。該方法的返回值是布爾值Boolean 類型的,當它返回為false 時,表示請求結束,後續的Interceptor 和Controller 都不會再執行;當返回值為true 時就會繼續調用下一個Interceptor 的preHandle 方法,如果已經是最後一個Interceptor 的時候就會是調用當前請求的Controller 方法。
- 方法postHandle:由preHandle 方法的解釋我們知道這個方法包括後面要說到的afterCompletion 方法都只能是在當前所屬的Interceptor 的preHandle 方法的返回值為true 時才能被調用。postHandle 方法,顧名思義就是在當前請求進行處理之後,也就是Controller 方法調用之後執行,但是它會在DispatcherServlet 進行視圖返回渲染之前被調用,所以我們可以在這個方法中對Controller 處理之後的ModelAndView 對象進行操作,比如說設置cookie,返回給前端。postHandle 方法被調用的方向跟preHandle 是相反的,也就是說先聲明的Interceptor 的postHandle 方法反而會後執行
- 方法afterCompletion:該方法也是需要當前對應的Interceptor 的preHandle 方法的返回值為true 時才會執行。顧名思義,該方法將在整個請求結束之後,也就是在DispatcherServlet 渲染了對應的視圖之後執行。這個方法的主要作用是用於進行資源清理工作的。
例:
@Component public class AuthInterceptor implements HandlerInterceptor { private static final String TOKEN_COOKIE = "token"; @Autowired private UserDao userDao; @Override public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) throws Exception { Map<String, String[]> map = req.getParameterMap(); map.forEach((k,v) ->req.setAttribute(k, Joiner.on(",").join(v))); String requestURI = req.getRequestURI(); if (requestURI.startsWith("/static") || requestURI.startsWith("/error")) { return true; } Cookie cookie = WebUtils.getCookie(req, TOKEN_COOKIE); if (cookie != null && StringUtils.isNoneBlank(cookie.getValue())) { User user = userDao.getUserByToken(cookie.getValue()); if (user != null) { req.setAttribute(CommonConstants.LOGIN_USER_ATTRIBUTE, user); UserContext.setUser(user); } } return true; } @Override public void postHandle(HttpServletRequest req, HttpServletResponse res, Object handler, ModelAndView modelAndView) throws Exception { String requestURI = req.getRequestURI(); if (requestURI.startsWith("/static") || requestURI.startsWith("/error")) { return ; } User user = UserContext.getUser(); if (user != null && StringUtils.isNoneBlank(user.getToken())) { String token = requestURI.startsWith("logout")? "" : user.getToken(); Cookie cookie = new Cookie(TOKEN_COOKIE, token); cookie.setPath("/"); cookie.setHttpOnly(false); res.addCookie(cookie); } } @Override public void afterCompletion(HttpServletRequest req, HttpServletResponse response, Object handler, Exception ex) throws Exception { UserContext.remove(); } }