SpringBoot内容协商(简单使用、源码解读、默认Converters、自定义Converters)

目录

  • 1. 内容协商
    • 1.1 简单使用
    • 1.2 源码解读
    • 1.3 WebMvcAutoConfiguration提供几种默认HttpMessageConverters
    • 1.4 自定义HttpMessageConverter支持yaml格式输出

1. 内容协商

1.1 简单使用

一套系统适配多端数据返回

内容协商

  • 基于请求头内容协商:(默认开启)
    1. 客户端向服务端发送请求,携带HTTP标准的Accept请求头application/json(默认支持,因为web场景导入了jackson处理的包jackson-core)、application/xml(需要手动设置)
    2. 服务端根据客户端请求头期望的数据类型进行动态返回
  • 基于请求参数内容协商:(需要手动开启)
    1. 发送请求: GET /get-user?format=json(默认支持)
    2. 匹配到@GetMapping(“/get-user”)
    3. 根据参数协商,返回json类型数据
    4. 发送请求: GET /get-user?format=xml, 返回xml类型数据(需要手动设置)

开启xml支持

  1. 先添加pom.xml依赖
<!-- 添加了依赖前,默认返回json,添加依赖后,默认返回xml -->
<dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId>
</dependency>
  1. 在Bean类上添加xml支持注解
@JacksonXmlRootElement    // 其实不加这个也可以
public class User {
......省略部分......
}

开启基于请求参数内容协商。application.properties参数设置如下

# 开启基于请求参数的内容协商功能。 默认为false功能不开启
spring.mvc.contentnegotiation.favor-parameter=true
# 指定内容协商时使用的参数名。默认是format
spring.mvc.contentnegotiation.parameter-name=type

示例:RestController如下:

package com.hh.springboot3test.controller;import com.hh.springboot3test.bean.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class ControllerTest {@GetMapping("/get-user")public User user() {return new User("jim");}
}

通过header头传递accept参数,和返回结果如下:
header头

通过请求参数,返回结果如下:
请求参数结果

1.2 源码解读

  • @ResponseBody由HttpMessageConverter处理:标注了@ResponseBody的返回值,将会由支持它的HttpMessageConverter写给浏览器
  1. 如果controller方法的返回值标注了@ResponseBody注解

    1. 请求进来先来到DispatcherServlet的doDispatch()进行处理
    2. 找到一个HandlerAdapter适配器。利用适配器执行目标方法
    3. RequestMappingHandlerAdapter通过调用invokeHandlerMethod()来执行目标方法
    4. 目标方法执行之前,准备好两个东西
      1. HandlerMethodArgumentResolver:参数解析器,确定目标方法每个参数值
      2. HandlerMethodReturnValueHandler:返回值处理器,确定目标方法的返回值该怎么处理
    5. RequestMappingHandlerAdapter里面的invokeAndHandle()真正执行目标方法
    6. 目标方法执行完成,会返回返回值对象
    7. 找到一个合适的返回值处理器HandlerMethodReturnValueHandler
    8. 最终找到RequestResponseBodyMethodProcessor能处理标注了 @ResponseBody注解的方法
    9. RequestResponseBodyMethodProcessor调用writeWithMessageConverters, 利用MessageConverter把返回值写出去
  2. HttpMessageConverter会先进行内容协商

    1. 遍历所有的MessageConverter看谁支持这种内容类型的数据

    2. 默认MessageConverter有以下
      MessageConverter

    3. 最终因为要json,所以MappingJackson2HttpMessageConverter支持写出json

    4. jackson用ObjectMapper把对象写出去

1.3 WebMvcAutoConfiguration提供几种默认HttpMessageConverters

● EnableWebMvcConfiguration -> DelegatingWebMvcConfiguration -> WebMvcConfigurationSupport -> addDefaultHttpMessageConverters添加了默认的MessageConverter。如下:
- ByteArrayHttpMessageConverter: 支持字节数据读写
- StringHttpMessageConverter: 支持字符串读写
- ResourceHttpMessageConverter:支持资源读写
- ResourceRegionHttpMessageConverter: 支持分区资源写出
- AllEncompassingFormHttpMessageConverter:支持表单xml/json读写
- MappingJackson2HttpMessageConverter: 支持请求响应体Json读写

系统提供默认的MessageConverter功能有限,仅用于json或者普通返回数据。额外增加新的内容协商功能,必须增加新的HttpMessageConverter

1.4 自定义HttpMessageConverter支持yaml格式输出

  1. 添加依赖,用于对Object进行转换
        <dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-yaml</artifactId></dependency>
  1. 编写一个YamlHttpMessageConverter
package com.hh.springboot3test.component;import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;public class MyYamlHttpMessageConverter extends AbstractHttpMessageConverter<Object> {//把对象转成yamlprivate ObjectMapper objectMapper = null;public MyYamlHttpMessageConverter() {// 告诉SpringBoot这个MessageConverter支持哪种媒体类型  super(new MediaType("text", "yaml", Charset.forName("UTF-8")));YAMLFactory factory = new YAMLFactory().disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER);this.objectMapper = new ObjectMapper(factory);}@Overrideprotected boolean supports(Class<?> clazz) {// 只要是对象类型,不是基本类型,则都支持return true;}// @RequestBody。对接收的yaml格式参数进行解析,这里不处理@Overrideprotected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {return null;}// @ResponseBody。把对象以yaml格式传输出去@Overrideprotected void writeInternal(Object methodReturnValue, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {// try-with写法,自动关流try (OutputStream os = outputMessage.getBody()) {this.objectMapper.writeValue(os, methodReturnValue);}}
}
  1. 在application.properties中,新增媒体类型
# 新增一种媒体类型
spring.mvc.contentnegotiation.media-types.yaml=text/yaml
  1. 通过WebMvcConfigurer,将MyYamlHttpMessageConverter添加到conveters
package com.hh.springboot3test.config;import com.hh.springboot3test.component.MyYamlHttpMessageConverter;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.util.List;@Configuration
public class WebConfig implements WebMvcConfigurer {// 添加一个能把对象转为yaml的messageConverter@Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {converters.add(new MyYamlHttpMessageConverter());}
}
  1. 测试。访问http://localhost:8080/get-user?type=yaml。效果如下:
    yaml内容协商效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/182357.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言--分段函数

要求&#xff1a;写一个程序&#xff0c;输入x的值&#xff0c;输出y的值 思路&#xff1a;定义两个变量&#xff0c;一个y&#xff0c;一个x&#xff0c;当x<1时&#xff0c;yx&#xff0c;当x>1&&x<10&#xff0c;y2x-1&#xff0c;当x>10,y3x-11.用一个…

Linux 服务器监控

服务器几乎与任何 IT 基础设施密不可分&#xff0c;Linux 是服务器兼容性最强的开源操作系统&#xff0c;因为它具有灵活性、一致性和安全性。大多数 Linux 服务器都设置了以下 Linux 操作系统的任何变体&#xff1a;Red Hat Enterprise Linux &#xff08;RHEL&#xff09;、D…

Linux Shell和权限

目录 Shell命令及运行原理 权限 1.文件基本属性 2.文件权限值的表示方法 3.文件访问权限的相关设置方法 3.(1)chmod 组名修改 3.(2)chmod 二进制修改 3.(3)chown 3.(4)chgrp 3.(5)umask 4.目录权限 Shell命令及运行原理 Linux的操作系统&#xff0c;狭义上是…

看看顶级外贸业务员是如何跟进客户的?

许多外贸业务员&#xff0c;都碰到过客户跟进上的困难。那到底外贸业务员如何跟进客户&#xff0c;才能越跟越近&#xff0c;最终成交呢&#xff1f;本篇文章设定了几个客户回复的场景&#xff0c;看看顶尖销售都是怎么应对的吧&#xff1f; 一 客户说暂时没有需求 1.问清楚客…

案例研究|腾讯音乐娱乐集团与JumpServer共探安全运维审计解决方案

近年来&#xff0c;得益于人民消费水平的提升以及版权意识的加强&#xff0c;用户付费意愿和在线用户数量持续增长&#xff0c;中国在线音乐市场呈现出稳定增长的发展态势。随着腾讯音乐于2018年12月上市&#xff0c;进一步推动了中国在线音乐市场的发展。 腾讯音乐娱乐集团&a…

数据可视化:地图

1.基础地图的使用 如何添加颜色表示层级 代码实现 """基础地图的使用 """ from pyecharts.charts import Map from pyecharts.options import VisualMapOpts# 准备地图对象 map Map() # 准备数据 data [("北京市", 9),("上海市…

WebGL:基础练习 / 简单学习 / demo / canvas3D

一、前置内容 canvas&#xff1a;理解canvas / 基础使用 / 实用demo-CSDN博客 WebGL&#xff1a;开始学习 / 理解 WebGL / WebGL 需要掌握哪些知识 / 应用领域 / 前端值得学WebGL吗_webgl培训-CSDN博客 二、在线运行HTML 用来运行WebGL代码&#xff0c;粘贴--运行&#xff…

LangChain+LLM实战---Midjourney(v5.1) Prompt深度剖析

原文&#xff1a;Anatomy of Midjourney Promps: In-Depth Study for effective Prompting Strategies — V5.1 examples 作者&#xff1a;Michael King 你是否曾经发现自己盯着Midjourney的空白画布&#xff0c;手指悬停在键盘上&#xff0c;让我问自己&#xff1a;“我应该…

前端面试题之CSS篇

1、css选择器及其优先级 标签选择器: 1类选择器、属性选择器、伪类选择器&#xff1a;10id选择器&#xff1a;100内联选择器&#xff08;style“”&#xff09;&#xff1a;1000!important&#xff1a;10000 2、display的属性值及其作用 属性值作用none元素不显示&#xff0c…

使用VNC链接远程桌面

一、本地VNC客户端 本地主要需要一个VNC客户端&#xff0c;用来远程连接服务器端的VNC&#xff08;在不安装Web版本VNC情况下&#xff09;。VNC客户端下载地址&#xff1a; VNC客户端下载 二、安装Xfce桌面环境 在远程服务器控制台中安装Xfce桌面&#xff08;这个桌面环境比…

CSC公派遭美德拒签|计算机专业老师终赴意大利都灵理工大学访学

C老师拟申报CSC访学项目&#xff0c;希望先申请美国&#xff0c;并做好了一旦拒签再申请其它国家的心理准备。我们先用普渡大学的邀请函助其申报CSC&#xff0c;并顺利获批&#xff0c;但不出所料地被美国拒签了&#xff1b;很快又申请到德国奥芬堡应用技术大学&#xff0c;但不…

【Linux】简单部署Yearning并结合内网穿透实现公网访问

文章目录 前言1. Linux 部署Yearning2. 本地访问Yearning3. Linux 安装cpolar4. 配置Yearning公网访问地址5. 公网远程访问Yearning管理界面6. 固定Yearning公网地址 前言 Yearning 简单&#xff0c;高效的MYSQL 审计平台 一款MYSQL SQL语句/查询审计工具&#xff0c;为DBA与开…

Jakarta-JVM篇

文章目录 一.前言1. 1 JVM-堆常用调参1.2 JVM-方法区常用参数1.3 JVM-codeCache 二.JVM内存结构三. 对象创建四. JVM垃圾回收算法4.1 可达性分析算法4.1.1 对象引用4.1.2 回收方法区. 4.2 分代回收4.3 标记清除4.4 标记复制4.5 标记整理 五.垃圾回收器5.1 根节点枚举5.2 安全点…

打造高效运营底座,极智嘉一体化软件系统彰显科技威能

在仓储成本和物流需求日益增加的今天&#xff0c;创新且高效的物流机器人解决方案能够显著提升物流运营效率&#xff0c;降低物流成本&#xff0c;实现智能化、精益化、一体化的物流管理。全球仓储机器人引领者极智嘉(Geek)以「一套系统&#xff0c;天生全能」为准则&#xff0…

python脚本-网页爬虫获取网页图片

python脚本-网页爬虫获取网页图片 代码 import requests import re import time url"http://10.9.47.154/python-spider/" # 爬取网站的url headers {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like …

亚马逊云科技大语言模型下的六大创新应用功能

目录 前言 亚马逊云科技的AI创新应用 ​编辑 Amazon CodeWhisperer Amazon CodeWhisperer产品的优势 更快地完成更多工作 自信地进行编码 增强代码安全性 使用收藏夹工具 自定义 CodeWhisperer 以获得更好的建议 如何使用Amazon CodeWhisperer 步骤 1 步骤 2 具体…

Flink源码解析八之任务调度和负载均衡

源码概览 jobmanager scheduler:这部分与 Flink 的任务调度有关。 CoLocationConstraint:这是一个约束类,用于确保某些算子的不同子任务在同一个 TaskManager 上运行。这通常用于状态共享或算子链的情况。CoLocationGroup & CoLocationGroupImpl:这些与 CoLocationCon…

【漏洞复现】IIS_7.o7.5解析漏洞

感谢互联网提供分享知识与智慧&#xff0c;在法治的社会里&#xff0c;请遵守有关法律法规 文章目录 1.1、漏洞描述1.2、漏洞等级1.3、影响版本1.4、漏洞复现1、基础环境2、漏洞扫描3、漏洞验证 1.5、修复建议 1.1、漏洞描述 漏洞原理&#xff1a; cgi.fix_path1 1.png/.php该…

WPF中依赖属性及附加属性的概念及用法

完全来源于十月的寒流&#xff0c;感谢大佬讲解 依赖属性 由依赖属性提供的属性功能 与字段支持的属性不同&#xff0c;依赖属性扩展了属性的功能。 通常&#xff0c;添加的功能表示或支持以下功能之一&#xff1a; 资源数据绑定样式动画元数据重写属性值继承WPF 设计器集成 …

【数据结构】单链表OJ题

前言: 本节博客将讲解单链表的反转&#xff0c;合并有序链表&#xff0c;寻找中间节点及约瑟夫问题 文章目录 一、反转链表二、合并有序链表三、链表的中间结点四、环形链表的约瑟夫问题 一、反转链表 要反转链表&#xff0c;我们需要遍历链表并改变每个节点的 next 指针&#…