使⽤ @ResponseBody 的处理流程
- 在 HandlerAdapter.handle() 的中完成了 Response 输出
- RequestMappingHandlerAdapter.invokeHandlerMethod()
- HandlerMethodReturnValueHandlerComposite.handleReturnValue()
- RequestResponseBodyMethodProcessor.handleReturnValue()
- HandlerMethodReturnValueHandlerComposite.handleReturnValue()
- RequestMappingHandlerAdapter.invokeHandlerMethod()
doDispatch()
1.获取handler -> handlerAdapter
1 2 3 4 5 6 7 8 9 10 | 。。。。 mappedHandler = getHandler(processedRequest); if (mappedHandler == null) { noHandlerFound(processedRequest, response); return; } // Determine handler adapter for the current request. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); 。。。。 |
2.AbstractHandlerMethodAdapter.handle -> RequestMappingHandlerAdapter handleInternal 调用请求方法
1 2 3 4 5 6 7 8 | protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception { 。。。 // No synchronization on session demanded at all... mav = invokeHandlerMethod(request, response, handlerMethod); } 。。。 } |
3.set returnHandler
1 2 3 4 5 6 7
| protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception { ... ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod); if (this.argumentResolvers != null) { invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers); } if (this.returnValueHandlers != null) { invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers); } ... } |
4.Invoke method
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs); setResponseStatus(webRequest); if (returnValue == null) { if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) { 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); } catch (Exception ex) { if (logger.isTraceEnabled()) { logger.trace(formatErrorForReturnValue(returnValue), ex); } throw ex; } } |
5.HandlerMethodReturnValueHandlerComposite handleReturnValue
1 2 3 4 5 6 7 8 9 | 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); } |
6.RequestResponseBodyMethodProcessor handleReturnValue
1 2 3 4 5 6 7 8 9 10 11 | 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); // Try even with null return value. ResponseBodyAdvice could get involved. writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage); } |
7.Convert message
default converter AbstractJackson2HttpMessageConverter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | protected <T> void writeWithMessageConverters(@Nullable T value, MethodParameter returnType, ServletServerHttpRequest inputMessage, ServletServerHttpResponse outputMessage) throws IOException, HttpMediaTypeNotAcceptableException, HttpMessageNotWritableException { 1... select mediaType "application/json" if (selectedMediaType != null) { 2 . .... convert if (genericConverter != null) { genericConverter.write(body, targetType, selectedMediaType, outputMessage); } else { ((HttpMessageConverter) converter).write(body, selectedMediaType, outputMessage); } } ... } |