RequestResponseBodyMethodProcessor
创始人
2024-05-30 07:43:20
0

既是一个参数解析器,也是一个返回结果处理器。
1.持有消息转换器的集合

protected final List> messageConverters;

2.作为参数解析器,例如对@RequestBody标识的参数进行解析

  • 判断是否支持当前类型的参数
@Override
public boolean supportsParameter(MethodParameter parameter) {return parameter.hasParameterAnnotation(RequestBody.class);
}
  • 进行解析
    RequestResponseBodyMethodProcessor根据请求的content-type和我们的参数以及Controller对象类型等信息挨个询问每个消息转化器是否支持解析当前HTTP消息。
@Override
public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {parameter = parameter.nestedIfOptional();//核心的参数解析Object arg = readWithMessageConverters(webRequest, parameter, parameter.getNestedGenericParameterType());//...return adaptArgumentIfNecessary(arg, parameter);
}

readWithMessageConverters()函数会将HTTP请求体中的JSON转为我们的Java对象,主要用到转换器的**canRead()和Read()**方法,其源码如下:

@Nullable
protected  Object readWithMessageConverters(HttpInputMessage inputMessage, MethodParameter parameter,Type targetType) throws IOException, HttpMediaTypeNotSupportedException, HttpMessageNotReadableException {//拿到请求类型MediaType contentType;boolean noContentType = false;try {contentType = inputMessage.getHeaders().getContentType();}//...//拿到我们的参数类型和Controller类型Class contextClass = parameter.getContainingClass();Class targetClass = (targetType instanceof Class ? (Class) targetType : null);//...//拿到HTTP请求类型HttpMethod httpMethod = (inputMessage instanceof HttpRequest ? ((HttpRequest) inputMessage).getMethod() : null);Object body = NO_VALUE;EmptyBodyCheckingHttpInputMessage message = null;try {message = new EmptyBodyCheckingHttpInputMessage(inputMessage);//开始遍历所有的HttpMessageConverter,看看谁支持将当前http请求内容转为我们的参数for (HttpMessageConverter converter : this.messageConverters) {Class> converterType = (Class>) converter.getClass();GenericHttpMessageConverter genericConverter =(converter instanceof GenericHttpMessageConverter ? (GenericHttpMessageConverter) converter : null);if (genericConverter != null ? genericConverter.canRead(targetType, contextClass, contentType) ://核心就是canRead,与我们参数解析器的support()功能一致(targetClass != null && converter.canRead(targetClass, contentType))) {if (message.hasBody()) {HttpInputMessage msgToUse =getAdvice().beforeBodyRead(message, parameter, targetType, converterType);//找到HttpMessageConverter后调用read方法进行转化body = (genericConverter != null ? genericConverter.read(targetType, contextClass, msgToUse) :((HttpMessageConverter) converter).read(targetClass, msgToUse));body = getAdvice().afterBodyRead(body, msgToUse, parameter, targetType, converterType);}else {body = getAdvice().handleEmptyBody(null, message, parameter, targetType, converterType);}break;}}}//...异常捕捉与日志记录return body;
}

3.作为返回值处理器,可以处理@ResponseeBody所标识方法的返回值

  • 返回值处理器处理返回值:
this.returnValueHandlers.handleReturnValue(returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {HandlerMethodReturnValueHandler handler = selectHandler(returnValue, returnType);if (handler == null) {throw new IllegalArgumentException("Unknown return value type: " + returnType.getParameterType().getName());}//处理返回值handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
}private HandlerMethodReturnValueHandler selectHandler(@Nullable Object value, MethodParameter returnType) {boolean isAsyncValue = isAsyncReturnValue(value, returnType);for (HandlerMethodReturnValueHandler handler : this.returnValueHandlers) {if (isAsyncValue && !(handler instanceof AsyncHandlerMethodReturnValueHandler)) {continue;}if (handler.supportsReturnType(returnType)) {return handler;}}return null;
}

supportsReturnType()是判断是否支持当前返回值,源码如下:

@Override
public boolean supportsReturnType(MethodParameter returnType) {return (AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResponseBody.class) ||returnType.hasMethodAnnotation(ResponseBody.class));
}
  • 处理返回值
    通过内容协商确定输出信息的类型,遍历消息转换器,寻找能够支持该类型的转换器,并进行转换。主要用到的方法是canWirte()和Write()。最终可以将JaveBean对象转换为Json。

相关内容

热门资讯

四年级种草莓作文300字(精... 四年级种草莓作文300字 篇一四年级种草莓我家有一块小菜园,爸爸妈妈带我一起种了许多蔬菜和水果。其中...
四年级游太公湖暑假作文(精简... 四年级游太公湖暑假作文 篇一我和家人一起游太公湖暑假到了,我和家人决定去太公湖游玩。太公湖是我们城市...
菊花四年级作文(实用6篇) 菊花四年级作文 篇一菊花的美丽我最喜欢的花是菊花,因为它们有着独特的美丽和芬芳的香味。每当秋天来临,...
四年级小学生家长寄语【优质6... 四年级小学生家长寄语 篇一亲爱的宝贝,你已经进入了四年级,我感到非常骄傲和自豪。这一年,你将会面临更...
小学四年级写景作文(通用6篇... 小学四年级写景作文 篇一:美丽的夏日公园今天是个晴朗的夏日,在我家附近有一个美丽的公园,我和妈妈一起...
小学四年级作文我的家乡衢州【... 小学四年级作文我的家乡衢州 篇一我家乡衢州是一个美丽而古老的城市。它位于浙江省中部,是一个历史悠久的...
和恐龙在一起四年级语文作文(... 和恐龙在一起四年级语文作文 篇一四年级的我有一个非常奇妙的朋友,他就是一只恐龙。虽然恐龙在人类的眼中...
四年级与安全有关的作文24篇... 四年级与安全有关的作文24篇 篇一标题:如何保护自己的个人隐私个人隐私是每个人都应该尊重和保护的重要...
小区里的猫四年级作文400字... 小区里的猫四年级作文400字 篇一小区里的猫我家住在一个安静而美丽的小区里,小区里有一只可爱的猫。这...
四年级300字想象篇作文怎么... 四年级300字想象篇作文怎么写 篇一我喜欢想象,想象可以让我进入一个神奇的世界。我可以想象自己是一只...
感动那一瞬间四年级作文500... 感动那一瞬间四年级作文500字88篇 篇一:爸爸的温暖拥抱那是一个寒冷的冬日,我正坐在教室里,心里有...
四年级的作文【经典6篇】 四年级的作文 篇一:我喜欢的动物作文一:我喜欢的动物我喜欢的动物是小狗。小狗是一种忠诚、可爱的动物。...
军训生活作文【经典3篇】 军训生活作文 篇一军训生活是一段难忘的经历,它不仅锻炼了我们的体魄,也培养了我们的意志品质。回想起那...
最美的秋天四年级作文大全【精... 最美的秋天四年级作文大全 篇一秋天是我最喜欢的季节,因为它给我带来了无数的美好回忆和欢乐时光。每当秋...
我的家乡大草原作文400字四... 我的家乡大草原作文400字四年级29篇 篇一:美丽的大草原我的家乡是一片美丽的大草原。大草原上绿草如...
神奇的魔法球四年级作文(最新... 神奇的魔法球四年级作文 篇一一天放学后,我在回家的路上发现了一个闪闪发光的球,它看起来非常神奇。我好...
我的榜样四年级作文(优选6篇... 我的榜样四年级作文 篇一我的榜样是我的爸爸。他是一个非常勤劳和有责任心的人。我记得有一次,我生病了,...
春风化雨润物无声抒情作文(优... 春风化雨润物无声抒情作文 篇一春天的来临,带来了温暖的春风和细雨,仿佛是大自然对万物的滋润和呵护。这...
我的妈妈四年级作文【实用6篇... 我的妈妈四年级作文 篇一我亲爱的妈妈妈妈是我最亲爱的人,她是我的好朋友,也是我的榜样。我非常喜欢和妈...
擦玻璃四年级作文200字【优... 擦玻璃四年级作文200字 篇一擦玻璃今天放学后,我回到家里看到妈妈正在擦玻璃。看到窗户上的灰尘,我忍...