溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

使用SpringBoot 攔截器怎么對(duì)請(qǐng)求進(jìn)行判斷

發(fā)布時(shí)間:2020-12-28 14:58:33 來(lái)源:億速云 閱讀:506 作者:Leah 欄目:開(kāi)發(fā)技術(shù)

使用SpringBoot 攔截器怎么對(duì)請(qǐng)求進(jìn)行判斷?針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

自定義注解

/**
 * 對(duì)比請(qǐng)求的用戶身份是否符合
 * @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 = "根據(jù)手機(jī)號(hào)來(lái)刪除用戶")
  @PostMapping(value = "/delete_phone")
  public BaseCommonResult<Integer> deletePhone(@CompareUser(value = "phone") String phone) {
    int i = userService.deleteByPhone(phone);
    return BaseCommonResult.success(i);
  }

參數(shù)解析器

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

/**
 * @author liuyalong
 * @date 2020/9/25 15:56
 */
public class BaseCurrentUserInterceptor implements HandlerMethodArgumentResolver {
  /**
   * 用于判定是否需要處理該參數(shù)注解,返回true為需要,
   * 并會(huì)去調(diào)用下面的方法resolveArgument。
   */
  @Override
  public boolean supportsParameter(MethodParameter parameter) {
    //只處理CurrentUser注解修飾的參數(shù)
    return parameter.hasParameterAnnotation(CompareUser.class);
  }

  /**
   * 對(duì)比用戶信息
   */
  @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() + "]");
    }

    /*
     * 獲取要驗(yàn)證的字段名
     */

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

    //獲取請(qǐng)求字段的值
    String paramValue = String.valueOf(webRequest.getParameter(paramName));

    //從請(qǐng)求頭中獲取已經(jīng)登錄的用戶
    String userName = webRequest.getHeader(AuthConstant.USER_TOKEN_HEADER);

    //對(duì)于root用戶,可以操作一切,所以直接返回
    if (!AuthConstant.ROOT_USER.equals(userName)) {
      //判斷身份是否一致,不一致就拋出異常,讓RestControllerAdvice處理
      if (userName == null || !userName.equals(paramValue)) {
        throw new NotSameAuthorException();
      }
    }
    //將參數(shù)原封不動(dòng)返回出去,需要還原回需要的類型
    WebDataBinder binder = binderFactory.createBinder(webRequest, parameterType, paramName);
    return binder.convertIfNecessary(paramValue, parameterType, parameter);
  }
}

配置WebMvcConfigurer

注意這里提供了兩種方式加載,因?yàn)?/p>

@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("/**");
  }

  //參數(shù)解析器,自定義的優(yōu)先級(jí)最低,所以會(huì)失效,
  // 解決方案是下面的 @PostConstruct ,把優(yōu)先級(jí)調(diào)最高
  // 但是這樣@PathParam @RequestParam就失效了,@CompareUser(value="xxx")可以完全替換@RequestParam功能
//  @Override
//  public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
//    resolvers.add(currentUserInterceptor);
//
//  }

  /**
   *參數(shù)解析器優(yōu)先級(jí)調(diào)最高
   */
  @PostConstruct
  public void init() {
    // 獲取當(dāng)前 RequestMappingHandlerAdapter 所有的 Resolver 對(duì)象
    List<HandlerMethodArgumentResolver> resolvers = requestMappingHandlerAdapter.getArgumentResolvers();
    List<HandlerMethodArgumentResolver> newResolvers = new ArrayList<>(resolvers.size() + 1);

    // 添加自定義參數(shù)解析器到集合首位
    newResolvers.add(currentUserInterceptor);

    // 添加 已注冊(cè)的 Resolver 對(duì)象集合
    newResolvers.addAll(resolvers);
    // 重新設(shè)置 Resolver 對(duì)象集合
    requestMappingHandlerAdapter.setArgumentResolvers(newResolvers);
  }
}

關(guān)于使用SpringBoot 攔截器怎么對(duì)請(qǐng)求進(jìn)行判斷問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI