SpringMvc HttpMessageConverter之@ResponseBody

咱們先看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數據。

至於如何返回給頁面,等下回填坑吧。

相關文章
相關標籤/搜索