自定義一個注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserAuthorization {
}
復制代碼
其中@Target注解解決這個自定義注解可以加載哪些成分上,比如方法、類、屬性
- TYPE 類,接口(包括注釋類型)或枚舉聲明
- FIELD 字段聲明(包括枚舉常量)
- METHOD 方法聲明
- PARAMETER 形式參數聲明
- CONSTRUCTOR 構造函數聲明
- LOCAL_VARIABLE 局部變量聲明
- ANNOTATION_TYPE 注釋類型聲明
- PACKAGE 包
- TYPE_PARAMETER 類型參數聲明
- TYPE_USE 使用類型
其中Retention注解決定這個自定義注解的生命周期
- SOURCE 注解只在java源文件中存在,注釋將被編譯后丟棄
- CLASS 編譯成.class文件后注解還在,被類加載器加載到內存中后就不存在了
- RUNTIME 注解的生命周期一直程序運行時都存在,可以以反射方式讀取它們
配置一個攔截器
@Configuration
public class WebAppConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
/**
* 添加攔截器
*/
registry.addInterceptor(new AuthorizationInterceptor2())
.addPathPatterns("/api/**");
}
}
復制代碼
攔截器的實現
public class AuthorizationInterceptor2 extends HandlerInterceptorAdapter {
/**
* Key的Request Key
*/
public static final String REQUEST_CURRENT_KEY = "REQUEST_CURRENT_KEY";
/**
* 存放鑒權信息的Header名稱
*/
private String httpHeaderName = "sessionId";
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
/**
* 如果不是映射到方法直接通過
*/
if (!(handler instanceof HandlerMethod)) {
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
String token = request.getHeader(httpHeaderName);
if (token != null && token.length() > 0) {
/**
* 根據token拿key,如果不為空則返回true
*/
String key = "";
if (key != null) {
request.setAttribute(REQUEST_CURRENT_KEY, key);
return true;
}
}
/**
* 如果驗證token失敗,並且方法或類注明了Authorization,返回錯誤
*/
if (method.getAnnotation(Authorization.class) != null || handlerMethod.getBeanType().getAnnotation(Authorization.class) != null) {
throw new ApiException(ApiConstants.SESSIONIDEXCEPTION, "權限異常");
}
request.setAttribute(REQUEST_CURRENT_KEY, null);
return true;
}
}
復制代碼
這樣就可以在類上或方法上加UserAuthorization 實現權限控制