SpringBoot响应处理之以Json数据返回的实现方法

目录
  • 一、示例代码
  • 二、返回值解析原理
  • 三、源代码分析(debug)
  • 四、内容协商机制
    • 1. 内容协商
    • 2. 内容协商原理重点源代码
    • 3. HttpMessageConverters消息转换器原理

一、示例代码

访问 localhost:8080/jsonTest —— 返回 json 格式的数据

@Controller
public class ResponseTestController {
    @ResponseBody // 标注 —— 自动返回json数据
    @GetMapping("/jsonTest")
    public Person testPerson(){
        Person person = new Person();
        person.setAge(20);
        person.setUserName("Liuwanqing");
        Pet pet = new Pet();
        pet.setName("huahua");
        pet.setAge("五个月");
        person.setPet(pet);
        return person;
    }
}

二、返回值解析原理

SpringBoot 支持的返回值类型是由返回值解析器决定的,SpringBoot 返回值类型如下:

ModelAndView

Model

View

SpringBoot共含15种返回值解析器决定了其支持15种返回值:

三、源代码分析(debug)

设置以下几处断点:

step into —— 返回值处理器逻辑

this.returnValueHandlers.handleReturnValue(returnValue, this.getReturnValueType(returnValue), mavContainer, webRequest);

1. 先找返回值处理器

HandlerMethodReturnValueHandler handler = this.selectHandler(returnValue, returnType);

2. 执行下列代码,找到符合要求的返回值处理器

在众多返回值处理器中找到符合要求的 —RequestResponseBodyMethodRrocessor

即 RequestResponseBodyMethodRrocessor 可处理标注了 @ResponseBody 注解的返回值

   private HandlerMethodReturnValueHandler selectHandler(@Nullable Object value, MethodParameter returnType) {
        boolean isAsyncValue = this.isAsyncReturnValue(value, returnType);
        Iterator var4 = this.returnValueHandlers.iterator();
        HandlerMethodReturnValueHandler handler;
        do {
            do {
                if (!var4.hasNext()) {
                    return null;
                }
                handler = (HandlerMethodReturnValueHandler)var4.next();
            } while(isAsyncValue && !(handler instanceof AsyncHandlerMethodReturnValueHandler));
        } while(!handler.supportsReturnType(returnType));
        return handler;
    }

3. 调用返回值处理器(interface HandlerMethodReturnValueHandler)处理:

判断是否支持这种类型的返回值,支持调用返回值处理器,调用 handleReturnValue 进行处理

public interface HandlerMethodReturnValueHandler {
    boolean supportsReturnType(MethodParameter var1);
    void handleReturnValue(@Nullable Object var1, MethodParameter var2, ModelAndViewContainer var3, NativeWebRequest var4) throws Exception;
}

4. RequestResponseBodyMethodRrocessor工作原理

关键代码:

    public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws IOException, HttpMediaTypeNotAcceptableException, HttpMessageNotWritableException {
        mavContainer.setRequestHandled(true);
        ServletServerHttpRequest inputMessage = this.createInputMessage(webRequest);
        ServletServerHttpResponse outputMessage = this.createOutputMessage(webRequest);
        this.writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage);
    }

处理返回值的方法

使用消息转换器(涉及内容协商机制,请移步下文内容协商机制)进行写出操作,消息转换器工作过程如下:

  1. 浏览器告知服务器其处理能力
  2. 服务器根据其自身能力,判断服务器能生产什么样的内容
  3. SpringMVC 遍历所有容器的底层 HttpMessageConverter, 看谁能处理

四、内容协商机制

1. 内容协商

浏览器告知服务器其需要什么类型的服务类型

浏览器可接受的类型:

服务器得到浏览器的处理能力:

服务器将返回内容转为浏览器能处理的形式

2. 内容协商原理重点源代码

   protected List<MediaType> getProducibleMediaTypes(HttpServletRequest request, Class<?> valueClass, @Nullable Type targetType) {
        Set<MediaType> mediaTypes = (Set)request.getAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);
        if (!CollectionUtils.isEmpty(mediaTypes)) {
            return new ArrayList(mediaTypes);
        } else if (this.allSupportedMediaTypes.isEmpty()) {
            return Collections.singletonList(MediaType.ALL);
        } else {
            List<MediaType> result = new ArrayList();
            Iterator var6 = this.messageConverters.iterator();
            while(true) {
                while(var6.hasNext()) {
                    HttpMessageConverter<?> converter = (HttpMessageConverter)var6.next();
                    if (converter instanceof GenericHttpMessageConverter && targetType != null) {
                        if (((GenericHttpMessageConverter)converter).canWrite(targetType, valueClass, (MediaType)null)) {
                            result.addAll(converter.getSupportedMediaTypes());
                        }
                    } else if (converter.canWrite(valueClass, (MediaType)null)) {
                        result.addAll(converter.getSupportedMediaTypes());
                    }
                }
                return result;
            }
        }
    }

3. HttpMessageConverters消息转换器原理

MessageConverter 规范

默认的MessageConverter

最终 MappingJackson2HttpMessageConverter 把对象转为JSON(利用底层的jackson的objectMapper转换的)

总结:

  1. 返回值处理器判断是否支持这种类型的返回值( supportsReturnType)
  2. 返回值处理器调用handleReturnValue 进行处理
  3. 以 @ResponseBody 注解为例,RequestResponseBodyMethodProcessor 可以处理返回值标
  4. 最后,利用 MessageConverters 进行处理 将数据写为json

到此这篇关于SpringBoot响应处理之以Json数据返回的实现方法的文章就介绍到这了,更多相关SpringBoot Json数据返回内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot响应处理实现流程详解

    目录 1.相关依赖 2.ReturnValueHandlers—返回值处理器 3.HttpMessageConvert—消息转换器 4.开启浏览器参数方式内容协商功能 1.相关依赖 web项目引入的启动器spring-boot-starter-web中含有 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-json</arti

  • SpringBoot响应处理之以Json数据返回的实现方法

    目录 一.示例代码 二.返回值解析原理 三.源代码分析(debug) 四.内容协商机制 1. 内容协商 2. 内容协商原理重点源代码 3. HttpMessageConverters消息转换器原理 一.示例代码 访问 localhost:8080/jsonTest —— 返回 json 格式的数据 @Controller public class ResponseTestController { @ResponseBody // 标注 -- 自动返回json数据 @GetMapping("/js

  • SpringBoot整合Web开发之Json数据返回的实现

    目录 本章概要 返回JSON数据 默认实现 自定义转换器 1. 使用Gson 2. 使用fastjson 静态资源访问 默认策略 自定义策略 1. 在配置文件中定义 2. Java编码定义 本章概要 返回JSON数据 静态资源访问 返回JSON数据 默认实现 JSON 是目前主流的前后端数据传输方式,Spring MVC中使用消息转换器HTTPMessageConverter对JSON的转换提供了很好的支持,在Spring Boot中更进一步,对相关配置做了进一步的简化.默认情况下,创建一个Sp

  • SpringBoot实现前后端、json数据交互以及Controller接收参数的几种常用方式

    目录 前言 获取参数的几种常用注解 一.请求路径参数get请求 二.Body参数POST请求 四.HttpServletRequest 五.参数校检 最终选择交互方式 参考文献 总结 前言 现在大多数互联网项目都是采用前后端分离的方式开发,前端人员负责页面展示和数据获取,后端负责业务逻辑处理和接口封装.当与前端交互的过程当中,常用json数据与前端进行交互,这样想取出前端传送过来的json数据的时候,就需要用到@RequestBody这个注解.@RequestBody注解用于读取http请求的内

  • jQuery处理json数据返回数组和输出的方法

    本文实例讲述了jQuery处理json数据返回数组和输出的方法.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: /*print the json object  *  *$("selector").print_r_json(json,opts) : return formatted string (and print)  *sprint_r_json : just return the string;  *print_r_json : return the format

  • JavaScript中解析JSON数据的三种方法

    概述 现在JSON格式在web开发中越来越受重视,特别是在使用ajax开发项目的过程中,经常需要将json格式的字符串返回到前端,前端解析成JS对象(JSON ). ECMA-262(E3)中没有将JSON概念写到标准中,还好在 ECMA-262(E5)中JSON的概念被正式引入了,包括全局的JSON对象和Date的toJSON方法. 解析JSON数据的三种方法 eval()方法 解析JSON数据的最常用方法是使用javascript的eval()方法,代码如下: 复制代码 代码如下: func

  • Laravel框架实现修改登录和注册接口数据返回格式的方法

    本文实例讲述了Laravel框架实现修改登录和注册接口数据返回格式的方法.分享给大家供大家参考,具体如下: 1.背景:需要将所有的数据返回格式统一成retCode/retMsg/data 2.登陆接口: 文件目录:app/Http/Controllers/Auth/LoginController 先写登陆接口是因为修改登录接口比注册接口要简单许多 登录接口中的第一句 use AuthenticatesUsers; 可以进去修改登录验证内容(默认是email+password登录),可以修改 va

  • jQuery调取jSon数据并展示的方法

    本文实例讲述了jQuery调取jSon数据并展示的方法.分享给大家供大家参考.具体如下: 以下代码是将页面中的展示部分 复制代码 代码如下: function searchProductlistByfilterCondition(index, type, sort, filterWord) {      //cite_html      var citem_html = '<div class="citem"><div class="citemtop&quo

  • 使用Java构造和解析Json数据的两种方法(详解二)

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON数据不须要任何特殊的 API 或工具包. 在www.json.org上公布了很多JAVA下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别.下面接着介绍用org.json构造和解析Json数据的方法

  • 使用Java构造和解析Json数据的两种方法(详解一)

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON数据不须要任何特殊的 API 或工具包. 在www.json.org上公布了很多JAVA下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别.下面首先介绍用json-lib构造和解析Json数据的方法

  • Android编程实现根据经纬度查询地址并对获取的json数据进行解析的方法

    本文实例讲述了Android编程实现根据经纬度查询地址并对获取的json数据进行解析的方法.分享给大家供大家参考,具体如下: 第一步:根据指定的URL从google 服务器上获得包含地址的json格式的数据(其还提供xml格式的,但json解析效率比xml高) private static StringBuffer getJSONData(String urlPath){ try { URL url = new URL(urlPath); HttpURLConnection httpURLCon

随机推荐