對大部分系統來說都需要權限管理來決定不同使用者可以看到哪些內容,那麼如何在Spring MVC中實現權限驗證呢?當然我們可以繼續使用servlet中的過濾器Filter來實作。但藉助於Spring MVC中的action攔截器我們可以實作註解式的權限驗證。
一.首先介紹action攔截器:
HandlerInterceptor是Spring MVC為我們提供的攔截器接口,來讓我們實作自己的處理邏輯,HandlerInterceptor 的內容如下:
public interface HandlerInterceptor { boolean preHandle( HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; void postHandle( HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception; void afterCompletion( HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception; }
可以看到介面有3個方法,其意義如下:
preHandle:在執行action裡面的處理邏輯之前執行,它回傳的是boolean,這裡如果我們回傳true在接著執行postHandle和afterCompletion,如果我們回傳false則中斷執行。
postHandle:在執行action裡面的邏輯後回傳視圖之前執行。
afterCompletion:在action回傳視圖後執行。
HandlerInterceptorAdapter適配器是Spring MVC為了方便我們使用HandlerInterceptor而對HandlerInterceptor 的預設實現,裡面的3個方法沒有做任何處理,在preHandle方法直接返回true,這樣我們繼承HandlerInterceptorAdapter後只需要實現3個方法中我們需要的方法即可,而不是像繼承HandlerInterceptor一樣不管是否需要3個方法都要實作。
當然借助HandlerInterceptor我們可以實現許多其它功能,例如日誌記錄、請求處理時間分析等,權限驗證只是其中之一。
二.下面我們就來一步一步來完成註解式權限驗證的功能。
首先新增一個帳號的Controller和登入的Action及檢視來模擬在沒有權限時跳到登陸頁面,內容分別如下:
com.demo.web.controllers套件中的AccountController.java:
package com.demo.web.controllers;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod; @Controller @RequestMapping(value = "/account")public class AccountController { @RequestMapping(value="/login", method = {RequestMethod.GET}) public String login(){ return "login"; } }
views資料夾下的視圖login.jsp:
nbsp;html PUBLIC "-//W3C//DTD HTML 4.0SpringMVC學習系列(9) 之 實作註解式權限驗證的程式碼詳解 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><meta><title>Insert title here</title> 这里是登录界面##新套件com. demo.web.auth,新增自訂註解AuthPassport,內容如下:
package com.demo.web.auth;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Inherited;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target; @Documented @Inherited @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME)public @interface AuthPassport { boolean validate() default true; }新增自己的攔截器實作AuthInterceptor繼承於HandlerInterceptorAdapter,內容如下:
package com.demo.web.auth;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.web.method.HandlerMethod;import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;public class AuthInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if(handler.getClass().isAssignableFrom(HandlerMethod.class)){ AuthPassport authPassport = ((HandlerMethod) handler).getMethodAnnotation(AuthPassport.class); //没有声明需要权限,或者声明不验证权限 if(authPassport == null || authPassport.validate() == false) return true; else{ //在这里实现自己的权限验证逻辑 if(false)//如果验证成功返回true(这里直接写false来模拟验证失败的处理) return true; else//如果验证失败 { //返回到登录界面 response.sendRedirect("account/login"); return false; } } } else return true; } }配置專案的springservlet-config.xml加入如下內容:
<interceptors> <!-- 国际化操作拦截器 如果采用基于(请求/Session/Cookie)则必需配置 --> <bean></bean> <!-- 如果不定义 mvc:mapping path 将拦截所有的URL请求 --> <bean></bean></interceptors>這樣在執行每個action方法是都會呼叫AuthInterceptor處理,當判斷action上有我們定義AuthPassport註解時就會執行裡面的權限驗證邏輯。 運行專案: 可以看到執行了我們在springservlet-config.xml定義的HelloworldController的index方法。
<!-- 如果当前请求为“/”时,则转发到“/helloworld/index" --><view-controller></view-controller>
下面我们在HelloworldController的index方法上加上自定义注解AuthPassport:
@AuthPassport @RequestMapping(value={"/index","/hello"})public ModelAndView index(){ ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("message", "Hello World!"); modelAndView.setViewName("index"); return modelAndView; }
重新运行项目:
可以看到正确执行了权限判断逻辑,这样我们只需要在我们在需要权限验证的action上加上这个注解就可以实现权限控制功能了。
注解式权限验证的内容到此结束。
以上就是SpringMVC学习系列(9) 之 实现注解式权限验证的代码详解的内容,更多相关内容请关注PHP中文网(www.php.cn)!