SpringMvc HttpMessageConverter之@ResponseBody
发布日期:2021-05-16 13:48:20 浏览次数:14 分类:博客文章

本文共 3356 字,大约阅读时间需要 11 分钟。

我们先看HttpMessageConverter的示意图,从图片可以看出它是多么的重要。在一条必经之路截道了的感觉。

先上我的测试例子:

jsp页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>
Insert title here

 

java代码:

@Controllerpublic class TestJson {    /**     * 如何返回json数据     * 1,加入3个jackson的jar包     * 2,编写对应的方法,使其返回json对应的对象或方法     * 3,在方法中加入@ResponseBody注解     */        @Autowired    private EmployeeDAO employeeDao;        @RequestMapping("testJson")    @ResponseBody    public Collection
testJson(){ return employeeDao.getAll().values(); }}

首先我们要知道HttpMessageConverter和@ResponseBody之间有什么联系。

  如果不使用@ResponseBody注解,那么我在业务方法(@RequestMapping注解)的Model中,或者Map中放入的值和我返回的字符串将组成ModelAndView对象。然后渲染视图。

  使用了@ResponseBody之后,会选择适当的处理器,比如json处理器,将我返回的值转换成相应的格式,写入到HttpOutputMessage中,写入到Response的body中去。

下面我们就先看看使用了@ResponseBody时,SpringMvc为我们做了什么?

从DispatcherServlet的handle方法

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

开始-->AbstractHandlerMethodAdapter类的handleInternal方法-->RequestMappingHandlerAdapter类的invokeHandleMethod方法-->ServletInvocableHandlerMethod类的invokeAndHandle方法

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数据。

至于如何返回给页面,等下回填坑吧。

上一篇:SpringMvc @RequestMapping原理
下一篇:SpringMvc渲染视图

发表评论

最新留言

感谢大佬
[***.8.128.20]2025年04月27日 12时03分30秒