zoukankan      html  css  js  c++  java
  • 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数据。

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

  • 相关阅读:
    POJ 2289 Jamie's Contact Groups / UVA 1345 Jamie's Contact Groups / ZOJ 2399 Jamie's Contact Groups / HDU 1699 Jamie's Contact Groups / SCU 1996 Jamie's Contact Groups (二分,二分图匹配)
    HDU 2389 Rain on your Parade / HUST 1164 4 Rain on your Parade(二分图的最大匹配)
    CJOJ 1494 【网络流24题】 搭配飞行员(二分图最大匹配)
    Luogu 1402 酒店之王(二分图最大匹配)
    CJOJ 1943 【重庆八中模拟赛】寻找代表元(二分图最大匹配)
    Luogu 2756 飞行员配对方案问题(二分图最大匹配)
    Luogu 1559 运动员最佳匹配问题(带权二分图最大匹配)
    Luogu 1894 [USACO4.2]完美的牛栏The Perfect Stall / POJ 1274 The Perfect Stall(二分图最大匹配)
    Conda和Python的国内安装源
    快速安装Rainbond——开源企业级Paas平台
  • 原文地址:https://www.cnblogs.com/javammc/p/8582952.html
Copyright © 2011-2022 走看看