咱們先看HttpMessageConverter的示意圖,從圖片能夠看出它是多麼的重要。在一條必經之路截道了的感受。javascript
先上個人測試例子:html
jsp頁面:java
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <script type="text/javascript" src="<%=request.getContextPath() %>/js/jquery-3.1.1.min.js"></script> </head> <body> <script type="text/javascript"> $(function(){ var args={}; var url="<%=request.getContextPath()%>/testJson"; $.post(url,args,function(result){ alert(result) }) }) </script> </body> </html>
java代碼:jquery
@Controller public class TestJson { /** * 如何返回json數據 * 1,加入3個jackson的jar包 * 2,編寫對應的方法,使其返回json對應的對象或方法 * 3,在方法中加入@ResponseBody註解 */ @Autowired private EmployeeDAO employeeDao; @RequestMapping("testJson") @ResponseBody public Collection<Employee> testJson(){ return employeeDao.getAll().values(); } }
首先咱們要知道HttpMessageConverter和@ResponseBody之間有什麼聯繫。web
若是不使用@ResponseBody註解,那麼我在業務方法(@RequestMapping註解)的Model中,或者Map中放入的值和我返回的字符串將組成ModelAndView對象。而後渲染視圖。json
使用了@ResponseBody以後,會選擇適當的處理器,好比json處理器,將我返回的值轉換成相應的格式,寫入到HttpOutputMessage中,寫入到Response的body中去。app
下面咱們就先看看使用了@ResponseBody時,SpringMvc爲咱們作了什麼?jsp
從DispatcherServlet的handle方法ide
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
開始-->AbstractHandlerMethodAdapter類的handleInternal方法-->RequestMappingHandlerAdapter類的invokeHandleMethod方法-->ServletInvocableHandlerMethod類的invokeAndHandle方法post
public final void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs); setResponseStatus(webRequest); if (returnValue == null) { if (isRequestNotModified(webRequest) || hasResponseStatus() || mavContainer.isRequestHandled()) { mavContainer.setRequestHandled(true); return; } } else if (StringUtils.hasText(this.responseReason)) { mavContainer.setRequestHandled(true); return; } mavContainer.setRequestHandled(false); try {
//處理返回的Map集合 this.returnValueHandlers.handleReturnValue(returnValue, getReturnValueType(returnValue), mavContainer, webRequest); } catch (Exception ex) { if (logger.isTraceEnabled()) { logger.trace(getReturnValueHandlingErrorMessage("Error handling return value", returnValue), ex); } throw ex; } }
從標紅部分點進去,
@Override public void handleReturnValue( Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception { //匹配到的返回值處理器是RequestResponseBodyMethodProcessor HandlerMethodReturnValueHandler handler = getReturnValueHandler(returnType); Assert.notNull(handler, "Unknown return value type [" + returnType.getParameterType().getName() + "]");
//處理器處理集合 handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest); }
在從標紅行點進去,
@Override public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws IOException, HttpMediaTypeNotAcceptableException { //表示是直接返回頁面的body,我的理解,不夠準確 mavContainer.setRequestHandled(true); if (returnValue != null) {
//把map轉爲json寫到outputMessage writeWithMessageConverters(returnValue, returnType, webRequest); } }
再日後就是調用系統默認處理json的類MappingJackson2HttpMessageConverter來轉換成json數據。
至於如何返回給頁面,等下回填坑吧。