1、是什么?

SpringBoot内容协商机制是一种实现了内容协商(Content Negotiation)的Web服务器,它可以根据客户端请求的不同,将响应返回给客户端。

在传统的Web服务器中,如果客户端请求的URL与服务器上的URL不一致,服务器就会返回一个错误响应,告诉客户端所请求的URL不存在或者不合法。而SpringBoot内容协商机制则可以根据客户端请求的URL和服务器上的规则,动态地将响应返回给客户端,使得客户端可以成功地获取到所请求的数据。

SpringBoot内容协商机制的实现,可以使得服务器的负载减轻,提高服务器的可扩展性和可维护性,同时也可以提高客户端的响应速度和用户体验。

2、能干啥?

SpringBoot内容协商机制可以实现以下功能:

1、根据URL的不同,将响应返回给客户端;

2、动态地将响应返回给客户端,使得客户端可以成功地获取到所请求的数据;

3、提高服务器的负载能力,提高服务器的可扩展性和可维护性;

4、提高客户端的响应速度和用户体验。

5、根据响应头的“Accept”字段的不同,选择不同的处理方式;

6、......

总之,SpringBoot内容协商机制可以帮助Web服务器更好地处理不同来源的数据,提高服务的质量和可靠性。

3、怎么玩?

首先明确一下,SpringBoot默认是以JSON形式处理数据

(1) 基于请求头Accept的内容协商机制(SpringBoot默认开启)

例如:当我们请求头携带Accept:applicatiom/json时服务端会给我们返回json数据

当我们请求头携带Accept:applicatiom/xml时服务端会给我们返回xml数据

(2) 基于请求参数的内容协商机制(需要手动开启)

例如:发送请求 http://localhost:8080/json?format=json ,优先返回 json 类型数据

当然想要实现基于请求参数的内容协商,需要进行以下几个配置

1.导入依赖

 <dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>

2.加入注解

@JacksonXmlRootElement // 支持写出xml文档
@Data
@AllArgsConstructor
public class User { private Integer id;
private String name;
private String email;
}

3.编写配置

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

接下来就会有如下的效果了

json:

xml:

4、如何自定义内容返回?

例如:增加yaml返回支持,我想实现一个返回yaml格式的内容协商机制

(1) 导入依赖
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
</dependency>
(2) 添加配置
spring:
mvc:
contentnegotiation:
favor-parameter: true # 开启基于请求参数的内容协商功能。 默认参数名:format。 默认此功能不开启
parameter-name: ly # 指定内容协商时使用的参数名。默认是 format
media-types:
yaml: application/yaml # 添加一种新的媒体配置
(3) 自定义一个HttpMessageConverter
package com.ly.component;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
import com.ly.entity.User;
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.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets; /**
* @author ly (个人博客:https://www.cnblogs.com/ybbit)
* @date 2023-06-22 20:49
* @tags 喜欢就去努力的争取
*/
public class YamlHttpMessageConverter extends AbstractHttpMessageConverter { private ObjectMapper objectMapper = null; public YamlHttpMessageConverter() {
super(new MediaType("application", "yaml", StandardCharsets.UTF_8));
var factory = new YAMLFactory().disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER);
this.objectMapper = new ObjectMapper(factory);
} @Override
protected boolean supports(Class clazz) {
// 只要是对象类型都支持
return true;
} /**
* 读数据的规则
*
* @param clazz
* @param inputMessage
* @return
* @throws IOException
* @throws HttpMessageNotReadableException
*/
@Override
protected Object readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
User user = null;
try (InputStream is = inputMessage.getBody()) {
ObjectReader objectReader = this.objectMapper.readerFor(clazz);
user = objectReader.readValue(is, User.class);
System.out.println("user = " + user);
} catch (Exception e) {
throw new RuntimeException(e);
}
return user;
} /**
* 写数据的规则
*
* @param methodReturnValue
* @param outputMessage
* @throws IOException
* @throws HttpMessageNotWritableException
*/
@Override
protected void writeInternal(Object methodReturnValue, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
try (OutputStream os = outputMessage.getBody()) {
this.objectMapper.writeValue(os, methodReturnValue);
}
}
}

SpringBoot内容协商机制的更多相关文章

  1. 深入理解SpringBoot核心机制《spring-boot-starter》

    深入理解SpringBoot核心机制<spring-boot-starter> 前言: 对于这几年java火爆天的springBoot我相信大家都有所使用过,在springBoot的项目中 ...

  2. SpringBoot工作机制

    1:前言 回顾探索Spring框架 1.spring ioc IoC其实有两种方式,一种就是DI,而另一种是DL,即Dependency Lookup(依赖查找),前者是当前软件实体被动接受其依赖的其 ...

  3. 深入springboot原理——一步步分析springboot启动机制(starter机制)

    前言 使用过springboot的同学应该已经知道,springboot通过默认配置了很多框架的使用方式帮我们大大简化了项目初始搭建以及开发过程.本文的目的就是一步步分析springboot的启动过程 ...

  4. SpringBoot学习(二)探究Springboot启动机制

    引言: SpringBoot为我们做的自动配置,确实方便快捷,但是对于新手来说,如果不大懂SpringBoot内部启动原理,以后难免会吃亏.所以这次博主就跟你们一起探究一下SpringBoot的启动原 ...

  5. SpringBoot原理—分析SpringBoot启动机制(starter机制)

    一:前言使用过springboot的同学应该已经知道,springboot通过默认配置了很多框架的使用方式帮我们大大简化了项目初始搭建以及开发过程.本文的目的就是一步步分析springboot的启动过 ...

  6. SpringBoot Starter机制 - 自定义Starter

    目录 前言 1.起源 2.SpringBoot Starter 原理 3.自定义 Starter 3.1 创建 Starter 3.2 测试自定义 Starter 前言         最近在学习Sp ...

  7. [译]谈谈SpringBoot 事件机制

    要"监听"事件,我们总是可以将"监听器"作为事件源中的另一个方法写入事件,但这将使事件源与监听器的逻辑紧密耦合. 对于实际事件,我们比直接方法调用更灵活.我们可 ...

  8. Springboot 系列(七)Spring Boot web 开发之异常错误处理机制剖析

    前言 相信大家在刚开始体验 Springboot 的时候一定会经常碰到这个页面,也就是访问一个不存在的页面的默认返回页面. 如果是其他客户端请求,如接口测试工具,会默认返回JSON数据. { &quo ...

  9. Spring MVC内置支持的4种内容协商方式【享学Spring MVC】

    每篇一句 十个光头九个富,最后一个会砍树 前言 不知你在使用Spring Boot时是否对这样一个现象"诧异"过:同一个接口(同一个URL)在接口报错情况下,若你用rest访问,它 ...

  10. Spring MVC内容协商实现原理及自定义配置【享学Spring MVC】

    每篇一句 在绝对力量面前,一切技巧都是浮云 前言 上文 介绍了Http内容协商的一些概念,以及Spring MVC内置的4种协商方式使用介绍.本文主要针对Spring MVC内容协商方式:从步骤.原理 ...

随机推荐

  1. 数据可视化【原创】vue+arcgis+threejs 实现海量建筑物房屋渲染,性能优化

    本文适合对vue,arcgis4.x,threejs,ES6较熟悉的人群食用. 先报备一下版本号 "vue": "^2.6.11" "@arcgis/ ...

  2. 通过商品API接口获取到数据后的分析和应用

    一.如果你想要分析商品API接口获取到的数据,可以按照如下的步骤进行: 了解API接口返回值的格式,如JSON格式.XML格式.CSV格式等,选择适合你的数据分析方式. 使用API请求工具(如Post ...

  3. [WPF]使用HLSL实现百叶窗动效

    百叶窗动画是制作PPT时常用的动画之一,本文将通过实现百叶窗动画效果的例子介绍在WPF中如何使用ShaderEffect.ShaderEffect是使用高级着色器语言(High Level Shadi ...

  4. [python] 在ubuntu中, 如何运行指定位置的py程序

    首先打开终端 Ctrl + Alt + T 运行py程序 进入py文件所在目录 (例如: cd 桌面) 运行py程序: python a.py

  5. 【krpano】KRPano测试开发专用浏览器

    KRPano技术解密网站:http://www.krpano.tech 在开发KRPano项目时候,每次测试时均需要打开测试服务器,或者上传到空间中才能进行测试,十分不方便. 因此本站提供了免费的KR ...

  6. Java 21新特性:Sequenced Collections(有序集合)

    在JDK 21中,Sequenced Collections的引入带来了新的接口和方法来简化集合处理.此增强功能旨在解决访问Java中各种集合类型的第一个和最后一个元素需要非统一且麻烦处理场景. 下面 ...

  7. 最快速搭建个人服务器图床siuuuuu

    @ 目录 1.服务器准备 2.docker 安装 (1)通过命令行的方式 (2)宝塔面板上安装 3.开启端口访问 什么是docker 4.docker安装minio 什么是minio 5.配置mini ...

  8. 彻底弄懂ip掩码中的网络地址、广播地址、主机地址

    本文为博主原创,转载请注明出处: 概念理解: IP掩码(或子网掩码)用于确定一个IP地址的网络部分和主机部分.它是一个32位的二进制数字,与IP地址做逻辑与运算,将IP地址划分为网络地址和主机地址两部 ...

  9. 前端三件套系例之CSS——响应式布局

    文章目录 1.什么是响应式设计 1-1 定义 1-2 响应式设计的优势 2.屏幕的相关概念 3.viewport 视口 3-1 什么是viewport 3-2 设置viewport 4.媒体查询 @m ...

  10. tiptopGP5.2链接所有表或报不存在函数处理

    修改交易的表时需要特别注意,改完要关联所有有关的表r.rb.rb pja_file 当链接提示不存在的函数调用,又无法确定具体是那个关联程序时, 可以在本函数内先定义这个报错的函数,重新链接时,系统会 ...