• SpringMvc HttpMessageConverter之@ResponseBody


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

    先上我的测试例子:

    jsp页面:

    <%@ 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代码:

    @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之间有什么联系。

      如果不使用@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数据。

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

  • 相关阅读:
    微信接口开发之高级篇系列【微信权限封装类WechatAuth】
    微信接口开发之高级篇系列【用户分组接口和生成带参数的二维码】
    微信接口开发之高级篇系列【网页授权获取用户基本信息】
    微信接口开发之高级篇系列【微信JS-SDK】
    微信接口开发之高级篇系列【网页授权详细说明【提供测试账号使用】】
    微信接口开发之高级篇系列【网页授权接口】
    历史SQL语句之一
    盘点2019 | 金融科技发展大事件~
    FinTech终于被正名!央行印发金融科技发展规划
    安装配置开源的laravel项目到本地环境
  • 原文地址:https://www.cnblogs.com/javammc/p/8582952.html
Copyright © 2020-2023  润新知