Springboot中使用自定義參數註解獲取 token 中用戶數據

使用自定義參數註解獲取 token 中User數據

使用背景

在springboot項目開發中須要從token中獲取用戶信息時一般的方式要經歷幾個步驟java

  1. 攔截器中截獲token
  2. TokenUtil工具類解析token中的用戶信息
  3. 把解析結果存入到成員變量中
  4. controller中經過TokenUtil工具類提供的靜態方法獲取用戶信息

下面是過程示例代碼git

/*--------1.攔截器中獲取---------*/
String token =request.getHeader("token")

/*--------2.解析---------*/
//若是沒過時且有效
if(!TokenUtil.isExpire(token)){
    //解析token把結果存入成員變量
    TokenUtil.decode(token);
}

/*--------3.controller中獲取---------*/
User currentUser=TokenUtil.getUser();

看上去也沒什麼複雜指處,可是若是在每一個Controller中都加上一句
User currentUser=TokenUtil.getUser();感受有些多餘(潛意識知道確定有更簡潔的方法能減小這裏所寫代碼)web

下面介紹一種使用自定義參數註解的方法簡化獲取結果spring

最後預期達到的效果

@{RequestMethod}Mapping(value="path")
public Object methodName(@CurrentUser User user){
    //...code
}

正文開始

1. 攔截器中的代碼(GlobalInterceptor.java)

public class GlobalInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token=request.getHeader("token");
        //判斷路徑須要攔截
        //....code

        //若是token有效
        if(!TokenUtil.isExpire(token)){
            User user = TokenUtil.getUser(token);
            //咱們將解析的用戶結果先放入session中
            request.getSession().setAttribut("currentUser",user);
        }

        return true;
    }
}

2. 註冊攔截器(CustomWebMvcConfigurer.java)

@Configuration
public class CustomWebMvcConfigurer implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
            //註冊攔截器
            //攔截規則根據實際狀況,請作更改 /** 指全部 /*指1級目錄
            registry.addInterceptor(new GlobalInterceptor()).addPathPatterns("/*/api/**");
            WebMvcConfigurer.super.addInterceptors(registry);
    }
}

3. 註解類 (CurrentUser.java)

@Target({ElementType.PARAMETER})//Annotation所修飾的對象範圍:方法參數
@Retention(RetentionPolicy.RUNTIME)//Annotation被保留時間:運行時保留(有效)
@Documented//標記註解:java工具文檔化
public @interface CurrentUser {
    
}

4. CurrentUser註解實現類(CurrentUserHandlerMethodArgReslover.java)

public class CurrentUserHandlerMethodArgReslover implements HandlerMethodArgumentResolver {

    /**
    * 判斷是否支持使用@CurrentUser註解的參數
    */
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        //若是該參數註解有@CurrentUser且參數類型是User
        return methodParameter.getParameterAnnotation(CurrentUser.class) != null &&methodParameter.getParameterType() == User.class;
    }

    /**
    * 注入參數值
    */
    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        //取得HttpServletRequest
        HttpServletRequest request= (HttpServletRequest) nativeWebRequest.getNativeRequest();
        //取出session中的User
        return (User)request.getSession().getAttribute("currentUser");
    }
}

5. 在SpringBoot啓動類中註冊 註解的實現類(ServerApplication.java)

@SpringBootApplication
public class ServerApplication extends WebMvcConfigurationSupport {

    /**
     * 啓動入口
     * @param args
     */
    public static void main(String[] args) {
        SpringApplication.run(ServerApplication.class,args);
    }

    @Override
    protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers){
        //註冊@CurrentUser註解的實現類
        argumentResolvers.add(new CurrentUserHandlerMethodArgReslover());
    }
}

6. 在Controller中使用

@GetMapping(value="/demo/api/testget")
public Object getTest(@CurrentUser User currentUser){
    System.out.println(currentUser);
    return currentUser;
}

到此就實現了預期的結果,回頭看發現雖然多寫了很多代碼,可是在用的時候仍是更加簡潔明瞭,美麗大方(給本身比個❤)api

gitbook上預覽此文章springboot

相關文章
相關標籤/搜索