• 自定义springmvc参数解析器


    实现spring HandlerMethodArgumentResolver接口

    通过使用@JsonArg自定义注解来解析json数据(通过fastjson的jsonPath),支持多个参数(@RequestBody只支持单个参数)

    自定义注解@JsonArg

    @Target({ElementType.PARAMETER})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface JsonArg {
        /**
         * @see <a href="https://github.com/alibaba/fastjson/wiki/JSONPath">https://github.com/alibaba/fastjson/wiki/JSONPath</a>
         */
        String value() default "";
    }
    

    参数解析器实现

    @Slf4j
    public class JsonPathArgumentResolver implements HandlerMethodArgumentResolver {
    
        private static final String JSONBODYATTRIBUTE = "JSON_REQUEST_BODY";
    
        @Override
        public boolean supportsParameter(MethodParameter parameter) {
            return parameter.hasParameterAnnotation(JsonArg.class);
        }
    
        @Override
        public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
            String body = getRequestBody(webRequest);
            String value = parameter.getParameterAnnotation(JsonArg.class).value();
            if (StringUtils.isBlank(value)) {
                value = parameter.getParameterName();
            }
            Object val = JSONPath.read(body, value);
            if (log.isDebugEnabled()) {
                log.debug("resolveArgument return class type:{}", val == null ? null : val.getClass().getName());
                log.debug("value:{}", val);
            }
            if (val instanceof JSONObject) {
                return JSON.parseObject(((JSONObject) val).toJSONString(), parameter.getParameterType());
            }
            if (val instanceof JSONArray) {
                ParameterizedType genericParameterType = (ParameterizedType) parameter.getGenericParameterType();
                // 泛型参数可能有多个,现在只处理了一个
                Type[] actualTypeArguments = genericParameterType.getActualTypeArguments();
                String typeName = actualTypeArguments[0].getTypeName();
                return JSON.parseArray(((JSONArray) val).toJSONString(), Class.forName(typeName));
            }
            //TODO 未实现基本类型之间互相转换
            return val;
        }
    
        private String getRequestBody(NativeWebRequest webRequest) {
            HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
            String jsonBody = (String) servletRequest.getAttribute(JSONBODYATTRIBUTE);
            if (jsonBody == null) {
                try {
                    String body = IOUtils.toString(servletRequest.getInputStream(), StandardCharsets.UTF_8);
                    servletRequest.setAttribute(JSONBODYATTRIBUTE, body);
                    return body;
                } catch (Exception e) {
                    log.error("read request body error:{}", e.getMessage());
                    throw new RuntimeException(e);
                }
            }
            return jsonBody;
        }
    }
    

    配置

    自定义参数解析器优先级低于spring提供的默认解析器,会被默认解析器处理

    @Configuration
    @EnableWebMvc
    // springboot 2.0实现 WebMvcConfigurer 接口
    public class WebMvcConfigurer extends WebMvcConfigurerAdapter {
    
        /**
         * prioritize Custom ArgumentMethodHandlers
         */
        @Autowired
        public void prioritizeCustomArgumentMethodHandlers(RequestMappingHandlerAdapter adapter) {
            List<HandlerMethodArgumentResolver> argumentResolvers = new ArrayList<>(adapter.getArgumentResolvers());
            List<HandlerMethodArgumentResolver> customResolvers = adapter.getCustomArgumentResolvers();
            argumentResolvers.removeAll(customResolvers);
            argumentResolvers.addAll(0, customResolvers);
            adapter.setArgumentResolvers(argumentResolvers);
        }
    
         
        /**
         * registry argumentResolvers
         */
        @Override
        public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
            argumentResolvers.add(new JsonPathArgumentResolver());
        }
    }
    

    使用

        @PostMapping("/test.do")
        public void test(@JsonArg String name) {
            log.debug("name:{}", name);
        }
    
  • 相关阅读:
    Android短信管家视频播放器代码备份
    深入理解Android的startservice和bindservice
    Android拦截外拨电话
    android中的目录结构介绍
    2013年最后的3个月,你想到了什么呢?
    如何通过Html网页调用本地安卓app?
    Textview文字监控(输入到某个字符后,进行操作)
    ASP.NET MVC5 网站开发实践(二) Member区域
    ASP.NET MVC5 网站开发实践(二) Member区域
    ASP.NET MVC5 网站开发实践(一)
  • 原文地址:https://www.cnblogs.com/wilwei/p/10244670.html
Copyright © 2020-2023  润新知