攔截器加注解可以實現登錄權限驗證等操作,我的應用場景也是為了驗證這個,下面是簡單的實現步驟
一、什么是攔截器?
攔截器是對action的一種攔截,可以在請求前后進行一些處理
可攔截controller和view內容
二、Spring中自定義攔截器步驟
1、Spring中繼承HandlerInterceptorAdapter或實現HandlerInterceptor接口
public class Auth58Interceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { return true; } }
2、重寫preHandler等方法
HandlerInterceptorAdapter下的有幾個方法分別處理攔截請求的操作前后的內容,可根據自己需要選擇方法重寫
業務處理請求之前:preHandle
該方法返回boolean類型值,如果為true繼續下面的內容,為false直接退出該請求,不會繼續執行了
preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
業務處理請求之后,DispatcherServlet渲染ModelAndView視圖之前:postHandle
preHandle返回true時才會執行這里
postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
業務處理請求之后,DispatcherServlet渲染了ModelAndView視圖之后:afterCompletion
preHandle返回true時才會執行這里
afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
有異步請求時觸發:afterConcurrentHandlingStarted
在preHandle返回true之后才執行這里,這里執行完成之后會觸發postHandle和afterCompletion
afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler)
3、在web.xml中注冊攔截器
可以設置多個interceptor攔截器,從上至下進行匹配攔截
mvc:mapping path="":匹配那種路徑可以命中攔截器,如果不配置或配置/**將會攔截所有Controller
mvc:exclude-mapping path="":排除該路徑不進行攔截,靜態資源進行攔截我這里會出問題,所以排除掉
bean class="":攔截器的類,包含包名的全路徑
例子如下:
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**" /><!--如果不配置或/**,將攔截所有的Controller--> <mvc:exclude-mapping path="/static/**" /> <mvc:exclude-mapping path="/views/**" /> <bean class="com.zhuanzhuan.zzappqa.annotations.Auth58Interceptor" /> </mvc:interceptor> </mvc:interceptors>
三、攔截器和注解配合使用
我這里用途是,判斷接口需要的權限,進而查看當前用戶是否有訪問全新
步驟1:攔截器重新preHandler()方法,解析自定義注解上的屬性值
步驟2:獲得當前請求信息中的用戶信息,從數據庫中拿到當前登錄用戶的權限
步驟3:通過步驟2獲得當前用戶權限和步驟1中限定的權限作對比,判斷是否允許繼續訪問或是跳轉到登錄等其他操作
一個未處理邏輯的例子如下:
攔截器代碼:
package com.xxx.annotations; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.lang.annotation.Annotation; public class Auth58Interceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { HandlerMethod handlerMethod = (HandlerMethod) handler; if(handlerMethod.getBeanType().isAnnotationPresent(Auth58.class)){//注意要用handlerMethod.getBeanType()獲得對象,不能通過getClass()獲得對象 System.out.println("命中攔截器"); return true; }else{ System.out.println("未命中攔截器"); return true; } } }
注意:要用handlerMethod.getBeanType()獲得對象,不能通過getClass()獲得對象
解析注解屬性值和進一步的判斷方法這里就不寫了,解析屬性值的上面注解那篇里有介紹
單獨業務邏輯各位就單獨處理吧