组件
HandlerMethodReturnValueHandler
返回值处理器接口
public interface HandlerMethodArgumentResolver {
// 是否支持处理该参数
boolean supportsParameter(MethodParameter var1);
// 解析返回值
Object resolveArgument(MethodParameter var1, ModelAndViewContainer var2, NativeWebRequest var3, WebDataBinderFactory var4) throws Exception;
}
HttpMessageConverter
处理HTTP请求和响应的转换器。
public interface HttpMessageConverter<T> {
// 对于该Media类型是否可读
boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);
boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);
// 获得当前消息转换器支持的类型
List<MediaType> getSupportedMediaTypes();
// 读写转换,将request或response中的参数转换为对应类型
T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException;
void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException;
}
AbstractHttpMessageConverter
HttpMessageConverter接口的基础实现
public abstract class AbstractHttpMessageConverter<T> implements HttpMessageConverter<T> {
// 消息转换器支持的Content-Type
private List<MediaType> supportedMediaTypes = Collections.emptyList();
// 默认编码
private Charset defaultCharset;
public boolean canRead(Class<?> clazz, @Nullable MediaType mediaType) {
// 是否支持类型和content-type
return supports(clazz) && canRead(mediaType);
}
// 开始read时转换
public final T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException {
return readInternal(clazz, inputMessage);
}
}
返回值解析
- 经过doInvoke(args),反射调用处理器方法获得返回值
protected Object doInvoke(Object... args) throws Exception {
ReflectionUtils.makeAccessible(getBridgedMethod());
try {
return getBridgedMethod().invoke(getBean(), args);
}
···异常处理
}
- ServletInvocableHandlerMethod中invokeAndHandle初步处理返回值,选择返回值解析器,通过返回值解析器来处理返回值
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
// 反射调用后的返回值
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
// 处理返回状态
setResponseStatus(webRequest);
// 如果返回值为空或response状态存在证明在处理器方法已经处理的response,无需经过视图解析,所以设置requestHandled的true,表示请求已经被处理了
if (returnValue == null) {
if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) {
disableContentCachingIfNecessary(webRequest);
mavContainer.setRequestHandled(true);
return;
}
}
else if (StringUtils.hasText(getResponseStatusReason())) {
mavContainer.setRequestHandled(true);
return;
}
mavContainer.setRequestHandled(false);
Assert.state(this.returnValueHandlers != null, "No return value handlers");
try {
// 调用返回值处理器处理返回值
this.returnValueHandlers.handleReturnValue(
returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
}
···抛出异常
}
- HandlerMethodReturnValueHandlerComposite调用handleReturnValue方法,根据返回值类型来选择返回值解析器解析返回值。
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);
}
- 这里分析RequestResponseBodyMethodProcessor返回值解析器,主要是通过消息转化器来转换返回值
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest)
throws IOException, HttpMediaTypeNotAcceptableException, HttpMessageNotWritableException {
mavContainer.setRequestHandled(true);
ServletServerHttpRequest inputMessage = createInputMessage(webRequest);
ServletServerHttpResponse outputMessage = createOutputMessage(webRequest);
// 使用对应的消息转换器,处理返回值
writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage);
}
- 如果已被处理返回null,不走视图解析,否则根据ModelAndViewContainer生成ModelAndView返回
private ModelAndView getModelAndView(ModelAndViewContainer mavContainer,
ModelFactory modelFactory, NativeWebRequest webRequest) throws Exception {
modelFactory.updateModel(webRequest, mavContainer);
// 如果已被处理返回null,不走视图解析
if (mavContainer.isRequestHandled()) {
return null;
}
ModelMap model = mavContainer.getModel();
// 创建返回的mav
ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model, mavContainer.getStatus());
// 如果返回值不为string则解析为视图
if (!mavContainer.isViewReference()) {
mav.setView((View) mavContainer.getView());
}
// 重定向属性处理
if (model instanceof RedirectAttributes) {
Map<String, ?> flashAttributes = ((RedirectAttributes) model).getFlashAttributes();
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
if (request != null) {
RequestContextUtils.getOutputFlashMap(request).putAll(flashAttributes);
}
}
return mav;
}
- 判断if (mv != null && !mv.wasCleared()),ModelAndView不为空则进行视图渲染