天天看點

springMVC自定義注解實作使用者行為驗證

最近在進行項目開發的時候需要對接口做Session驗證

@Retention:注解的保留位置         
          @Retention(RetentionPolicy.SOURCE)    //注解僅存在于源碼中,在class位元組碼檔案中不包含
         @Retention(RetentionPolicy.CLASS)     //預設的保留政策,注解會在class位元組碼檔案中存在,但運作時無法獲得,
         @Retention(RetentionPolicy.RUNTIME)   //注解會在class位元組碼檔案中存在,在運作時可以通過反射擷取到
      
       @Target:注解的作用目标
            
        @Target(ElementType.TYPE)   //接口、類、枚舉、注解
        @Target(ElementType.FIELD) //字段、枚舉的常量
        @Target(ElementType.METHOD) //方法
        @Target(ElementType.PARAMETER) //方法參數
        @Target(ElementType.CONSTRUCTOR)  //構造函數
        @Target(ElementType.LOCAL_VARIABLE)//局部變量
        @Target(ElementType.ANNOTATION_TYPE)//注解
        @Target(ElementType.PACKAGE) ///包   
     
        @Document:說明該注解将被包含在javadoc中
     
       @Inherited:說明子類可以繼承父類中的該注解      

1、自定義一個注解@AuthCheckAnnotation

@Documented //文檔生成時,該注解将被包含在javadoc中,可去掉
@Target(ElementType.METHOD)//目标是方法 
@Retention(RetentionPolicy.RUNTIME) //注解會在class中存在,運作時可通過反射擷取  
@Inherited
public @interface AuthLoginAnnotation {
  /**
     * 檢查是否已登入(注解的參數)
     * 
     * @return true-檢查;預設不檢查為false
     */
    boolean check() default false; 
}



注解方法不能有參數。
注解方法的傳回類型局限于原始類型,字元串,枚舉,注解,或以上類型構成的數組。
注解方法可以包含預設值。
注解可以包含與其綁定的元注解,元注解為注解提供資訊,有四種元注解類型:


  1. @Documented – 表示使用該注解的元素應被javadoc或類似工具文檔化,它應用于類型聲明,類型聲明的注解會影響用戶端對注解元素的使用。如果一個類型聲明添加了Documented注解,那麼它的注解會成為被注解元素的公共API的一部分。

  2. @Target – 表示支援注解的程式元素的種類,一些可能的值有TYPE, METHOD, CONSTRUCTOR, FIELD等等。如果Target元注解不存在,那麼該注解就可以使用在任何程式元素之上。

  3. @Inherited – 表示一個注解類型會被自動繼承,如果使用者在類聲明的時候查詢注解類型,同時類聲明中也沒有這個類型的注解,那麼注解類型會自動查詢該類的父類,這個過程将會不停地重複,直到該類型的注解被找到為止,或是到達類結構的頂層(Object)。

  4. @Retention – 表示注解類型保留時間的長短,它接收RetentionPolicy參數,可能的值有SOURCE(源檔案中起作用), CLASS, 以及RUNTIME(保留到運作時起作用)。      

2、定義一個相應的攔截器,在springMVC配置檔案中進行配置

  攔截器:

  spring為我們提供了org.springframework.web.servlet.handler.HandlerInterceptorAdapter這個擴充卡,繼承此類,可以非常友善的實作自己的攔截器。可以根據我們的需要重寫preHandle、postHandle、afterCompletio方法。

  分别實作預處理、後處理(調用了Service并傳回ModelAndView,但未進行頁面渲染)、傳回處理(已經渲染了頁面)     在preHandle中,可以進行編碼、安全控制等處理;     在postHandle中,有機會修改ModelAndView;     在afterCompletion中,可以根據ex是否為null判斷是否發生了異常,進行日志記錄。

public class AuthCheckInteceptor extends HandlerInterceptorAdapter {
    @Autowired
    UserInfoService userInfoService ;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        
        HandlerMethod methodHandler=(HandlerMethod) handler;
        AuthCheckAnnotation auth=methodHandler.getMethodAnnotation(AuthCheckAnnotation.class);
     //如果方法中添加了@AuthCheckAnnotation 這裡的auth不為null
     //如果@AuthCheckAnnotation(check=false) 這裡的auth為false,即不用進行攔截驗證,@AuthCheckAnnotation預設為前面定義的true  
        if(auth!=null&&!auth.check()){
           return true;  
        }
        UserInfo user=(UserInfo)request.getSession().getAttribute(Constants.SESSION_USER);
        try {
            userInfoService.login(request, user);
            return true;
        } catch (Exception e) {
            request.getRequestDispatcher("login.do").forward(request, response);
            return false;
        }
    }

}      

在springMVC.xml檔案中添加攔截器

<mvc:interceptors>
            <mvc:interceptor>
            <mvc:mapping path="/*.do"  />
            <bean  class="com.party.common.interceptor.AuthCheckInteceptor"/>        
        </mvc:interceptor>
    </mvc:interceptors>      

3、在springMVC controller中使用執行個體

@AuthCheckAnnotation(check=true)
    @RequestMapping("doLogin")
    @ResponseBody
    public Object doLogin(HttpServletRequest request,HttpServletResponse response){
        .......
        return RetMessage.toJson(responseBody);
    }