本文中介紹我在簡單的實際應用中,針對登陸用戶的訪問權限問題的具體實現,總體設計以下圖:spring
圖中請求進入Spring容器後會對用戶的有效性、權限進行驗證,只有驗證都經過以後才能進入實際業務邏輯。spring-mvc
上圖的實現使用Spring MVC的HandleInterceptor、HandlerInterceptorAdapter實現,下文中將一一介紹到。mvc
HandlerInterceptor接口須要實現類管理請求執行前、執行後、和請求處理完成後所須要執行的動做。代碼以下:app
public interface HandlerInterceptor { boolean preHandle(HttpServletRequest var1,HttpServletResponse var2, Object var3) throws Exception; void postHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3, ModelAndView var4) throws Exception; void afterCompletion(HttpServletRequest var1, HttpServletResponse var2, Object var3, Exception var4) throws Exception; }
preHandle
:對HTTP請求進行預處理,返回true則請求繼續,返回false則須要對Response進行響應postHandle
:在HTTP請求實際業務邏輯完成後(View渲染以前),處理須要作的動做afterCompletion
:在View渲染完成以後,處理須要的動做若是操做都須要進行控制,能夠直接繼承該接口並一一實現其中的方法。但有些時候咱們並不須要實現這麼多的操做,例如:如今我要對訪問的路徑進行校驗,則我只須要實現preHandle
方法就能夠知足,這裏要用到它的適配器HandlerInterceptorAdapter
,代碼以下:ide
public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor { public HandlerInterceptorAdapter() { } public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { } }
afterConcurrentHandlingStarted
:該適配器中還對當前攔截器開始執行後的動做進行了攔截處理,適用於在進行驗證以前對HTTP請求作一些統一的處理接着,咱們繼承該適配器並重寫其中的方法就能夠達到咱們的目的了,在這裏以個人權限檢查程序片斷爲例,代碼以下:post
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 從請求中拿到token String account = request.getParameter(ACCOUNT_KEY); String token = request.getParameter(TOKEN_KEY); // 打印Token和請求地址 LOGGER.info("Account------->{}", account); LOGGER.info("Token--------->{}", token); LOGGER.info("ReqUrl-------->{}", request.getRequestURI()); // 任意驗證屬性爲空->從新登陸 if (StringUtils.isEmpty(account) || StringUtils.isEmpty(token)) { response.sendRedirect(request.getContextPath() + "/err/needLogin"); return false; } // 驗證用戶有效性. boolean flag = validateAccount(request, account, token); if (!flag) { // 用戶權限驗證未經過->從新登陸 response.sendRedirect(request.getContextPath() + "/err/needLogin"); return false; } // 驗證路徑權限(AntPathMatcher實現) boolean authFlag = authPath(request, account); // 打印驗證結果 LOGGER.info("UserAuth----->{}", flag); LOGGER.info("PathAuth----->{}", authFlag); if (flag && authFlag) { return true; } else { // 未經過路徑權限驗證,跳轉到錯誤URL response.sendRedirect(request.getContextPath() + "/err/notAllow"); } return false; }
這裏根據個人驗證邏輯我只實現了preHandle
方法,其中使用AntPathMatcher實現路徑匹配的實現會在下一篇中詳細介紹。實現類完成後須要配置生效,那麼在spring的配置文件中,咱們能夠這麼寫,代碼以下:設計
<!--Spring 路徑攔截器配置--> <mvc:interceptors> <mvc:interceptor> <!--匹配路徑--> <mvc:mapping path="/**"/> <!--從匹配路徑移除不須要匹配的路徑--> <mvc:exclude-mapping path="/user/login"/> <mvc:exclude-mapping path="/user/secode"/> <mvc:exclude-mapping path="/user/passwd"/> <mvc:exclude-mapping path="/err/*"/> <mvc:exclude-mapping path="/news/**"/> <!--該攔截器的實現(上面咱們完成的類)--> <bean class="cn.creditease.app.util.PathInterceptor"/> </mvc:interceptor> </mvc:interceptors>
不要忘了引入Spring Schema:code
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
這樣咱們就經過Spring的攔截器實現了URL訪問權限校驗。xml