HandlerMethodArgumentResolver

由于之前用@RequestParam无法接受request payload 正文格式为json格式的字符串,只能使用@RequestBody整个接收,觉得麻烦,但是spring自带的参数解析器不具有这种功能,只能尝试着用自定义参数解析器去解决。

自定义解析器需要实现HandlerMethodArgumentResolver接口,HandlerMethodArgumentResolver接口包含两个接口:

接口说明: 
supportsParameter:用于判定是否需要处理该参数分解,返回true为需要,并会去调用下面的方法resolveArgument。 
resolveArgument:真正用于处理参数分解的方法,返回的Object就是controller方法上的形参对象。

1、自定义注解

package com.manqian.crm.resolver;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface JsonParam {

    String value();

    boolean required() default true;

    String defaultValue() default "";
}

若不想自定义注解,可以直接在实现HandlerMethodArgumentResolver的supportsParameter直接返回true

2、自定义参数解析器,实现HandlerMethodArgumentResolver接口

 1 package com.manqian.crm.resolver;
 2 
 3 import com.jayway.jsonpath.JsonPath;
 4 import com.jayway.jsonpath.PathNotFoundException;
 5 import com.manqian.crm.api.exception.ParamCheckException;
 6 import org.apache.commons.io.IOUtils;
 7 import org.springframework.context.annotation.Configuration;
 8 import org.springframework.core.MethodParameter;
 9 import org.springframework.web.bind.support.WebDataBinderFactory;
10 import org.springframework.web.context.request.NativeWebRequest;
11 import org.springframework.web.method.support.HandlerMethodArgumentResolver;
12 import org.springframework.web.method.support.ModelAndViewContainer;
13 
14 import javax.servlet.http.HttpServletRequest;
15 import java.io.IOException;
16 
17 public class JsonPathArgumentResolver implements HandlerMethodArgumentResolver {
18 
19     private static final String JSON_REQUEST_BODY = "JSON_REQUEST_BODY";
20 
21     //判断是否支持要转换的参数类型
22     @Override
23     public boolean supportsParameter(MethodParameter parameter) {
24         return parameter.hasParameterAnnotation(JsonParam.class);
25     }
26 
27     //当支持后进行相应的转换
28     @Override
29     public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
30         String body = getRequestBody(webRequest);
31         Object val = null;
32 
33         try {
34             val = JsonPath.read(body, parameter.getParameterAnnotation(JsonParam.class).value());
35             if (parameter.getParameterAnnotation(JsonParam.class).required() && val == null) {
36                 throw new ParamCheckException(parameter.getParameterAnnotation(JsonParam.class).value() + "不能为空");
37             }
38         } catch (PathNotFoundException exception) {
39             System.out.println(exception.getStackTrace());
40             if (parameter.getParameterAnnotation(JsonParam.class).required()) {
41 //                throw new ParamCheckException(parameter.getParameterAnnotation(JsonParam.class).value() + "不能为空");
42                 throw exception;
43             }
44         }
45         return val;
46     }
47 
48     private String getRequestBody(NativeWebRequest webRequest) {
49         HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
50         String jsonBody = (String) servletRequest.getAttribute(JSON_REQUEST_BODY);
51         if (jsonBody == null) {
52             try {
53                 jsonBody = IOUtils.toString(servletRequest.getInputStream());
54                 servletRequest.setAttribute(JSON_REQUEST_BODY, jsonBody);
55             } catch (IOException e) {
56                 throw new RuntimeException(e);
57             }
58         }
59         return jsonBody;
60 
61     }
62 
63 }

3、注册自定义参数解析器 
springboot方式: 
1、

 1 package com.demo;
 2 
 3 import java.util.List;
 4 
 5 import org.springframework.boot.autoconfigure.SpringBootApplication;
 6 import org.springframework.web.method.support.HandlerMethodArgumentResolver;
 7 import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
 8 
 9 import com.demo.mvc.component.MultiPersonArgumentResolver;
10 import com.demo.mvc.component.PersonArgumentResolver;
11 
12 @SpringBootApplication
13 public class WebMvcConfiguration extends WebMvcConfigurationSupport {
14 
15     @Override
16     protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
17 
18         // 注册JsonPathArgumentResolver的参数分解器
19         argumentResolvers.add(new JsonPathArgumentResolver());
20     }
21 }

2、

 1 package com.manqian.crm.resolver;
 2 
 3 import org.springframework.context.annotation.Configuration;
 4 import org.springframework.web.method.support.HandlerMethodArgumentResolver;
 5 import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
 6 
 7 import java.util.List;
 8 
 9 @Configuration
10 public class ClientResourcesConfig extends WebMvcConfigurerAdapter {
11 
12     @Override
13     public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
14 //        super.addArgumentResolvers(argumentResolvers);
15         argumentResolvers.add(new JsonPathArgumentResolver());
16     }
17 }

传统XML格式:

1、

1 <mvc:annotation-driven>
2       <mvc:argument-resolvers>
3         <bean class="com.manqian.crm.resolver.JsonPathArgumentResolver"/>
4       </mvc:argument-resolvers>
5 </mvc:annotation-driven>

2、

1 <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
2     <property name="jsonPathArgumentResolver">
3           <bean class="com.manqian.crm.resolver.JsonPathArgumentResolver"/>
4     </property>
5 </bean>

使用: 
1、依赖: 

com.jayway.jsonpath 
json-path 

2、controller方法使用@JsonParam接收参数

http://blog.csdn.net/u010187242/article/details/73647670

 

posted on 2018-03-01 14:15  让代码飞  阅读(155)  评论(0)    收藏  举报

导航

一款免费在线思维导图工具推荐:https://www.processon.com/i/593e9a29e4b0898669edaf7f?full_name=python