美文网首页
自定义参数解析器HandlerMethodArgumentRes

自定义参数解析器HandlerMethodArgumentRes

作者: chanyi | 来源:发表于2020-06-10 09:17 被阅读0次

    1、解决的问题

    加了@ResponseBody注解的方法,请求的方式是post的json格式,但如果我们也要通过post的application/x-www-form-urlencoded格式访问此接口。在不改变此接口的情况下。通过修改参数解析器HandlerMethodArgumentResovler来兼容两种请求方法。

    2、思路

    根据不同的content-type使用不同参数解析处理器。
    Content-Type为application/x-www-form-urlencoded,使用ServletModelAttributeMethodProcessor解析器
    Content-Type非application/x-www-form-urlencoded,使用RequestResponseBodyMethodProcessor解析器

    3、代码实现

    定义自己的参数解析器,继承HandlerMethodArgumentResolver

    
    /**
     * 自定义参数解析器
     * 功能:实现不同类型参数的解析
     * 使用@RequestBody注解,Content-Type为application/x-www-form-urlencoded,使用ServletModelAttributeMethodProcessor解析器
     * 使用@RequestBody注解,Content-Type非application/x-www-form-urlencoded,使用RequestResponseBodyMethodProcessor解析器
     *
     * @author lilei
     * @since 2020/05/09
     */
    @Log4j
    public class CustomMethodArgumentResolver implements HandlerMethodArgumentResolver {
    
      private RequestResponseBodyMethodProcessor requestResponseBodyMethodProcessor;
    
      private ServletModelAttributeMethodProcessor servletModelAttributeMethodProcessor;
    
      private final String APPLICATION_X_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded";
    
      private final String MULTIPART_FORM_DATA = "multipart/form-data";
    
      public CustomMethodArgumentResolver(
          RequestResponseBodyMethodProcessor requestResponseBodyMethodProcessor,
          ServletModelAttributeMethodProcessor servletModelAttributeMethodProcessor) {
        this.requestResponseBodyMethodProcessor = requestResponseBodyMethodProcessor;
        this.servletModelAttributeMethodProcessor = servletModelAttributeMethodProcessor;
      }
    
      /**
       *  参数解析器适用参数条件
       *
       * @param methodParameter
       * @return 使用@RequestBody注解 返回true,未使用返回false
       * @tips 可以使用自定义注解
       */
      @Override
      public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.hasParameterAnnotation(RequestBody.class);
      }
    
      /**
       * 参数解析
       * @param methodParameter
       * @param modelAndViewContainer
       * @param nativeWebRequest
       * @param webDataBinderFactory
       * @return
       * @throws Exception
       */
      @Override
      public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
        if (request == null) {
          throw new CustomrException(JsonResultCode.CODE_REQUEST_NULL.getName());
        }
        String contentType = request.getContentType();
        //更加请求contentType不同使用不同解析器
        log.info("contentType:"+contentType);
        if (contentType.contains(APPLICATION_X_WWW_FORM_URLENCODED)||contentType.contains(MULTIPART_FORM_DATA)) {
          log.info("Processor:"+servletModelAttributeMethodProcessor);
          return servletModelAttributeMethodProcessor.resolveArgument(methodParameter, modelAndViewContainer, nativeWebRequest, webDataBinderFactory);
        }
        log.info("Processor:"+requestResponseBodyMethodProcessor);
        return requestResponseBodyMethodProcessor.resolveArgument(methodParameter, modelAndViewContainer, nativeWebRequest, webDataBinderFactory);
      }
    }
    

    注册参数解析器

    /**
     * 配置注册参数解析器
     */
    @Configuration
    @Log4j
    public class ResolverConfig {
    
      private final RequestMappingHandlerAdapter requestMappingHandlerAdapter;
    
      public ResolverConfig(RequestMappingHandlerAdapter requestMappingHandlerAdapter) {
        this.requestMappingHandlerAdapter = requestMappingHandlerAdapter;
      }
    
      @PostConstruct
      private void addArgumentResolvers() {
        log.info("start add argument resolvers...");
        // 获取到的是不可变的集合
        List<HandlerMethodArgumentResolver> argumentResolvers = requestMappingHandlerAdapter.getArgumentResolvers();
    CustomMethodArgumentResolver customMethodArgumentResolver = getCustomMethodArgumentResolver(argumentResolvers);
        //新建参数解析器列表,然后将新列表添加到requestMappingHandlerAdapter中
        List<HandlerMethodArgumentResolver> newArgumentResolverList = new ArrayList<>(argumentResolvers.size() + 1);
        // 将自定义方法参数解析器放置在第一个,并保留原来的解析器
        newArgumentResolverList.add(customMethodArgumentResolver );
        newArgumentResolverList.addAll(argumentResolvers);
        requestMappingHandlerAdapter.setArgumentResolvers(newArgumentResolverList);
        log.info("add argument resolvers end!!!");
      }
    
      /**
       * 获取自定义方法参数解析器
       * @param argumentResolversList
       * @return
       */
      private CustomMethodArgumentResolver getCustomMethodArgumentResolver(List<HandlerMethodArgumentResolver> argumentResolversList) {
        // 解析Content-Type为application/json的默认解析器
        RequestResponseBodyMethodProcessor requestResponseBodyMethodProcessor = null;
        // 解析Content-Type为application/x-www-form-urlencoded的默认解析器
        ServletModelAttributeMethodProcessor servletModelAttributeMethodProcessor = null;
    
        if (argumentResolversList == null) {
          throw new CustomResolverException(JsonResultCode.CODE_RESOLVER_NULL.getName(),JsonResultCode.CODE_RESOLVER_NULL.getCode());
        }
        for (HandlerMethodArgumentResolver argumentResolver : argumentResolversList) {
          if (requestResponseBodyMethodProcessor != null && servletModelAttributeMethodProcessor != null) {
            break;
          }
          if (argumentResolver instanceof RequestResponseBodyMethodProcessor) {
            requestResponseBodyMethodProcessor = (RequestResponseBodyMethodProcessor) argumentResolver;
            continue;
          }
          if (argumentResolver instanceof ServletModelAttributeMethodProcessor) {
            servletModelAttributeMethodProcessor = (ServletModelAttributeMethodProcessor) argumentResolver;
          }
        }
        if (requestResponseBodyMethodProcessor == null || servletModelAttributeMethodProcessor == null) {
          throw new CustomResolverException(JsonResultCode.CODE_RESOLVER_VALUE_NULL.getName(),JsonResultCode.CODE_RESOLVER_VALUE_NULL.getCode());
        }
        return new CustomMethodArgumentResolver(requestResponseBodyMethodProcessor, servletModelAttributeMethodProcessor);
      }
    }
    

    相关文章

      网友评论

          本文标题:自定义参数解析器HandlerMethodArgumentRes

          本文链接:https://www.haomeiwen.com/subject/xoqutktx.html