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

作者:刘婉晴 时间:2023-12-21 12:21:47 

一、示例代码

访问 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种返回值:

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

三、源代码分析(debug)

设置以下几处断点:

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

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;
   }

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

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. 内容协商

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

浏览器可接受的类型:

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

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

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

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

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

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 规范

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

默认的MessageConverter

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

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

总结:

  1. 返回值处理器判断是否支持这种类型的返回值( supportsReturnType)

  2. 返回值处理器调用handleReturnValue 进行处理

  3. 以 @ResponseBody 注解为例,RequestResponseBodyMethodProcessor 可以处理返回值标

  4. 最后,利用 MessageConverters 进行处理 将数据写为json

来源:https://blog.csdn.net/liuwanqing233333/article/details/127090965

标签:SpringBoot,Json,数据返回,响应处理
0
投稿

猜你喜欢

  • Java排序算法总结之希尔排序

    2022-07-16 13:19:11
  • android侧滑菜单控件DrawerLayout使用方法详解

    2023-02-02 23:58:43
  • java9中gc log参数迁移

    2022-06-28 03:21:01
  • 一文详解Jetpack Android新一代导航管理Navigation

    2022-12-08 20:40:14
  • c#高效的线程安全队列ConcurrentQueue<T>的实现

    2021-07-27 11:01:05
  • Android 扫描WIFI权限详解

    2023-07-03 11:34:32
  • Java 将PPT幻灯片转为HTML文件的实现思路

    2022-12-12 12:00:35
  • Android编程常用技巧实例总结

    2022-11-30 20:27:44
  • IDEA 设置显示内存的使用情况和内存回收的方法

    2023-10-08 15:51:25
  • Java String转换时为null的解决方法

    2022-08-25 08:16:00
  • C# 一个WCF简单实例

    2023-07-12 20:53:43
  • Java螺旋矩阵处理方法详解

    2021-09-24 02:14:55
  • c# 使用HtmlAgilityPack解析Html

    2021-06-22 11:50:11
  • JSON中optString和getString方法的区别

    2021-09-06 03:46:14
  • 介绍java中Pair(配对)

    2021-09-03 10:15:39
  • EditText监听方法,实时的判断输入多少字符

    2021-08-16 11:32:36
  • Andriod 资源文件之存取操作

    2021-11-22 09:26:52
  • Java中的阻塞队列详细介绍

    2023-12-14 15:00:49
  • jenkins+maven+svn自动部署和发布的详细图文教程

    2023-08-24 05:18:07
  • android开发教程之子线程中更新界面

    2022-11-17 04:41:42
  • asp之家 软件编程 m.aspxhome.com