SpringBootMVC实现⾃定义RequestBody注解实现环境:SpringBoot 2.1.1,JDK 1.8
⼀、MVC实现RequestBody注解源码解析
1. @RequestBody
源码:
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestBody {
/**
* Whether body content is required.
* <p>Default is {@code true}, leading to an exception thrown in case
* there is no body content. Switch this to {@code false} if you prefer
* {@code null} to be passed when the body content is {@code null}.
* @since 3.2
*/
boolean required() default true;
}
@Target(ElementType.PARAMETER):Target定义注解的作⽤⽬标,ElementType.PARAMETER作⽤在⽅法参数
@Retention(RetentionPolicy.RUNTIME):注解会在class字节码⽂件中存在,在运⾏时可以通过反射获取到
@Documented:说明该注解被包含在javadoc中
2. RequestResponseBodyMethodProcessor
官⽅解释:
Resolves method arguments annotated with {@code @RequestBody} and handles return values from methods
annotated with {@code @ResponseBody} by reading and writing to the body of the request or response with an {@link HttpMessageConverter}.
源码中的继承关系
public class RequestResponseBodyMethodProcessor extends AbstractMessageConverterMethodProcessor
public abstract class AbstractMessageConverterMethodProcessor extends AbstractMessageConverterMethodArgumentResolver implements HandlerMeth AbstractMessageConverterMethodProcessor:使⽤HttpMessageConverters解析response body和request body的参数值
Extends {@link AbstractMessageConverterMethodArgumentResolver} with the ability to handle method return values by writing to the response with {@link HttpMessageConverter HttpMessageCo
nverters}
AbstractMessageConverterMethodArgumentResolver:使⽤HttpMessageConverters解析request body参数值的基类
A base class for resolving method argument values by reading from the body of a request with {@link
HttpMessageConverter HttpMessageConverters}.
RequestResponseBodyMethodProcessor对@RequestBody的绑定及实现源码:
public class RequestResponseBodyMethodProcessor extends AbstractMessageConverterMethodProcessor {
...
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(RequestBody.class);
}
/**
* Throws MethodArgumentNotValidException if validation fails.
* @throws HttpMessageNotReadableException if {@link RequestBody#required()}
* is {@code true} and there is no body content or if there is no suitable
* converter to read the content with.
*/
@Override
public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
parameter = stedIfOptional();
Object arg = readWithMessageConverters(webRequest, parameter, NestedGenericParameterType());
String name = VariableNameForParameter(parameter);
if (binderFactory != null) {
WebDataBinder binder = ateBinder(webRequest, arg, name);
if (arg != null) {
validateIfApplicable(binder, parameter);
if (BindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {
throw new MethodArgumentNotValidException(parameter, BindingResult());
}
}
if (mavContainer != null) {
mavContainer.addAttribute(BindingResult.MODEL_KEY_PREFIX + name, BindingResult());
}
}
return adaptArgumentIfNecessary(arg, parameter);
}
...
}
supportsParameter⽅法实现与@RequestBody绑定,resolveArgument实现具体解析
⼆、⾃定义RequestBody
1. ⾃定义注解
import java.lang.annotation.*;
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyBody {
}
2. Resolver
import MethodParameter;
import org.verter.HttpMessageConverter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.t.request.NativeWebRequest;
import org.hod.support.ModelAndViewContainer;
spring mvc和boot区别import org.springframework.web.hod.annotation.AbstractMessageConverterMethodArgumentResolver;
import java.util.Iterator;
import java.util.List;
/**
* Description: 继承AbstractMessageConverterMethodArgumentResolver实现RequestBody⽅式解析
* 也可直接实现HandlerMethodArgumentResolver类⾃定义解析⽅式
*/
public class MyBodyResolver extends AbstractMessageConverterMethodArgumentResolver {
public KIMBodyResolver(List<HttpMessageConverter<?>> converters) {
super(converters);
}
public MyBodyResolver(List<HttpMessageConverter<?>> converters, List<Object> requestResponseBodyAdvice) {
super(converters, requestResponseBodyAdvice);
}
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(MyBody.class);//绑定注解
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactor
String Header("token");
//判断头部token是否存在
if (null==token||token.isEmpty()){
throw new Exception("token is null");
}
//调⽤AbstractMessageConverterMethodArgumentResolver类中readWithMessageConverters⽅法
Object args = readWithMessageConverters(webRequest, parameter, ParameterType());
return args;
}
}
3. 将Resolver添加⼊配置中
quest.MyBodyResolver;
import t.annotation.Configuration;
import org.verter.HttpMessageConverter;
import org.verter.json.MappingJackson2HttpMessageConverter; import org.hod.support.HandlerMethodArgumentResolver;
import org.springframework.fig.annotation.EnableWebMvc;
import org.springframework.fig.annotation.WebMvcConfigurer;
import java.util.ArrayList;
import java.util.List;
@Configuration
@EnableWebMvc
public class KIMConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>(); //添加消息转换器
converters.add(new MappingJackson2HttpMessageConverter());
//消息转换器与Resolver绑定
resolvers.add(new MyBodyResolver(converters));
}
}
也可以上的⽅式添加配置。
MVC⾃定义@RequestBody与类似
三、HttpMessageConverter<>消息转换器
如有谬误,欢迎各位⼤佬斧正!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论