完成自定义的参数配置器替换默认的参数配置器之后,一个后台接口,既可以处理表单中的参数,也可以处理请求体中的json参数。但有些业务场景,要求一个后台接口,只能处理表单中的参数数据。这时,自定义的参数解析器将无法满足这个业务需求。因此,需要对其进行进一步的改造。
实现方案:增加自定义注解,来区分默认配置和增强配置。如果后台接口标注了自定义的注解,将保持springmvc的原有功能,即只有标注了@RequestBody注解的接口才能处理json数据。
实现步骤:
1、自定义注解
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Maintain {
}
2、升级参数处理器
public class MyHandlerMethodArgumentResolverV2 implements HandlerMethodArgumentResolver {
private final String CONTENT_TYPE_JSON = "application/json";
private RequestResponseBodyMethodProcessor json;
private ServletModelAttributeMethodProcessor defaultResolver;
public MyHandlerMethodArgumentResolverV2(RequestResponseBodyMethodProcessor json,
ServletModelAttributeMethodProcessor defaultResolver
) {
this.json = json;
this.defaultResolver = defaultResolver;
}
@Override
public boolean supportsParameter(MethodParameter parameter) {
return true;
}
@Override
public Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
boolean hasMaintainAnnotation = parameter.hasParameterAnnotation(Maintain.class);
if (hasMaintainAnnotation ){
//标注了Maintain注解,表示恢复原样功能
return keepMaintain(parameter,mavContainer,webRequest,binderFactory);
}else {
return keepEnhance(parameter,mavContainer,webRequest,binderFactory);
}
}
/**
*
* 保持原有功能
*/
protected Object keepMaintain(MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory)throws Exception{
if (json.supportsParameter(parameter)){
return json.resolveArgument(parameter,mavContainer,webRequest,binderFactory);
}
return defaultResolver.resolveArgument(parameter,mavContainer,webRequest,binderFactory);
}
/**
* 省略RequestBody注解
*/
protected Object keepEnhance(MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory)throws Exception{
String contentType = webRequest.getHeader("Content-Type");
if (StringUtils.startsWithIgnoreCase(contentType,CONTENT_TYPE_JSON)) {
return json.resolveArgument(parameter,mavContainer,webRequest,binderFactory);
}
return defaultResolver.resolveArgument(parameter,mavContainer,webRequest,binderFactory);
}
}
3、测试类
@RestController
@RequestMapping("test02")
public class TestController2 {
@RequestMapping("test1")
public Student test1(@Maintain Student s){
System.out.println(s);
return s;
}
}
4、测试参数

