1. 程式人生 > 程式設計 >vue使用require.context實現動態註冊路由

vue使用require.context實現動態註冊路由

應用場景舉例:

當不同身份的使用者請求一個介面時,用來校驗使用者某些身份,這樣可以對單個欄位資料進行精確許可權控制,具體看程式碼註釋

自定義註解

/**
 * 對比請求的使用者身份是否符合
 * @author liuyalong
 * @date 2020/9/25 16:03
 */
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface CompareUser {
  /**
   * The name of the request parameter to bind .
   */
  @AliasFor("name") String value() default "";
  @AliasFor("value") String name() default "";
}

給controller的欄位添加註解

  @ApiOperation(value = "刪除使用者",notes = "根據手機號來刪除使用者")
  @PostMapping(value = "/delete_phone")
  public BaseCommonResult<Integer> deletePhone(@CompareUser(value = "phone") String phone) {
    int i = userService.deleteByPhone(phone);
    return BaseCommonResult.success(i);
  }

引數解析器

記得繼承後加@Component,這裡是Base...所以不用

/**
 * @author liuyalong
 * @date 2020/9/25 15:56
 */
public class BaseCurrentUserInterceptor implements HandlerMethodArgumentResolver {
  /**
   * 用於判定是否需要處理該引數註解,返回true為需要,
   * 並會去呼叫下面的方法resolveArgument。
   */
  @Override
  public boolean supportsParameter(MethodParameter parameter) {
    //只處理CurrentUser註解修飾的引數
    return parameter.hasParameterAnnotation(CompareUser.class);
  }

  /**
   * 對比使用者資訊
   */
  @Override
  public Object resolveArgument(MethodParameter parameter,ModelAndViewContainer mavContainer,NativeWebRequest webRequest,WebDataBinderFactory binderFactory) throws Exception {
    CompareUser parameterAnnotation = parameter.getParameterAnnotation(CompareUser.class);

    Class<?> parameterType = parameter.getParameterType();
    if (parameterAnnotation == null) {
      throw new IllegalArgumentException("Unknown parameter type [" + parameterType.getName() + "]");
    }

    /*
     * 獲取要驗證的欄位名
     */

    //檢查是否給欄位取了別名
    String paramName = "".equalsIgnoreCase(parameterAnnotation.name()) ? parameterAnnotation.value() : parameterAnnotation.name();
    if ("".equalsIgnoreCase(parameterAnnotation.name())) {
      //從引數中獲取定義的欄位名
      paramName = parameter.getParameter().getName();
    }

    //獲取請求欄位的值
    String paramValue = String.valueOf(webRequest.getParameter(paramName));

    //從請求頭中獲取已經登入的使用者
    String userName = webRequest.getHeader(AuthConstant.USER_TOKEN_HEADER);

    //對於root使用者,可以操作一切,所以直接返回
    if (!AuthConstant.ROOT_USER.equals(userName)) {
      //判斷身份是否一致,不一致就丟擲異常,讓RestControllerAdvice處理
      if (userName == null || !userName.equals(paramValue)) {
        throw new NotSameAuthorException();
      }
    }
    //將引數原封不動返回出去,需要還原回需要的型別
    WebDataBinder binder = binderFactory.createBinder(webRequest,parameterType,paramName);
    return binder.convertIfNecessary(paramValue,parameter);
  }
}

配置WebMvcConfigurer

注意這裡提供了兩種方式載入,因為

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
  @Autowired
  private HandlerInterceptor handlerInterceptor;

  @Autowired
  private HandlerMethodArgumentResolver currentUserInterceptor;

  @Autowired
  private RequestMappingHandlerAdapter requestMappingHandlerAdapter;

  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(handlerInterceptor).addPathPatterns("/**");
  }

  //引數解析器,自定義的優先順序最低,所以會失效,// 解決方案是下面的 @PostConstruct,把優先順序調最高
  // 但是這樣@PathParam @RequestParam就失效了,@CompareUser(value="xxx")可以完全替換@RequestParam功能
//  @Override
//  public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
//    resolvers.add(currentUserInterceptor);
//
//  }

  /**
   *引數解析器優先順序調最高
   */
  @PostConstruct
  public void init() {
    // 獲取當前 RequestMappingHandlerAdapter 所有的 Resolver 物件
    List<HandlerMethodArgumentResolver> resolvers = requestMappingHandlerAdapter.getArgumentResolvers();
    List<HandlerMethodArgumentResolver> newResolvers = new ArrayList<>(resolvers.size() + 1);

    // 新增自定義引數解析器到集合首位
    newResolvers.add(currentUserInterceptor);

    // 新增 已註冊的 Resolver 物件集合
    newResolvers.addAll(resolvers);
    // 重新設定 Resolver 物件集合
    requestMappingHandlerAdapter.setArgumentResolvers(newResolvers);
  }
}

效果

只有特定身份人員才可以刪除操作

以上就是SpringBoot 攔截器和自定義註解判斷請求是否合法的詳細內容,更多關於SpringBoot 攔截器和自定義註解的資料請關注我們其它相關文章!