省略@RequestBody注解(2)

完成自定义的参数配置器替换默认的参数配置器之后,一个后台接口,既可以处理表单中的参数,也可以处理请求体中的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、测试参数