SpringBoot内容协商机制
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内容协商机制的更多相关文章
- 深入理解SpringBoot核心机制《spring-boot-starter》
深入理解SpringBoot核心机制<spring-boot-starter> 前言: 对于这几年java火爆天的springBoot我相信大家都有所使用过,在springBoot的项目中 ...
- SpringBoot工作机制
1:前言 回顾探索Spring框架 1.spring ioc IoC其实有两种方式,一种就是DI,而另一种是DL,即Dependency Lookup(依赖查找),前者是当前软件实体被动接受其依赖的其 ...
- 深入springboot原理——一步步分析springboot启动机制(starter机制)
前言 使用过springboot的同学应该已经知道,springboot通过默认配置了很多框架的使用方式帮我们大大简化了项目初始搭建以及开发过程.本文的目的就是一步步分析springboot的启动过程 ...
- SpringBoot学习(二)探究Springboot启动机制
引言: SpringBoot为我们做的自动配置,确实方便快捷,但是对于新手来说,如果不大懂SpringBoot内部启动原理,以后难免会吃亏.所以这次博主就跟你们一起探究一下SpringBoot的启动原 ...
- SpringBoot原理—分析SpringBoot启动机制(starter机制)
一:前言使用过springboot的同学应该已经知道,springboot通过默认配置了很多框架的使用方式帮我们大大简化了项目初始搭建以及开发过程.本文的目的就是一步步分析springboot的启动过 ...
- SpringBoot Starter机制 - 自定义Starter
目录 前言 1.起源 2.SpringBoot Starter 原理 3.自定义 Starter 3.1 创建 Starter 3.2 测试自定义 Starter 前言 最近在学习Sp ...
- [译]谈谈SpringBoot 事件机制
要"监听"事件,我们总是可以将"监听器"作为事件源中的另一个方法写入事件,但这将使事件源与监听器的逻辑紧密耦合. 对于实际事件,我们比直接方法调用更灵活.我们可 ...
- Springboot 系列(七)Spring Boot web 开发之异常错误处理机制剖析
前言 相信大家在刚开始体验 Springboot 的时候一定会经常碰到这个页面,也就是访问一个不存在的页面的默认返回页面. 如果是其他客户端请求,如接口测试工具,会默认返回JSON数据. { &quo ...
- Spring MVC内置支持的4种内容协商方式【享学Spring MVC】
每篇一句 十个光头九个富,最后一个会砍树 前言 不知你在使用Spring Boot时是否对这样一个现象"诧异"过:同一个接口(同一个URL)在接口报错情况下,若你用rest访问,它 ...
- Spring MVC内容协商实现原理及自定义配置【享学Spring MVC】
每篇一句 在绝对力量面前,一切技巧都是浮云 前言 上文 介绍了Http内容协商的一些概念,以及Spring MVC内置的4种协商方式使用介绍.本文主要针对Spring MVC内容协商方式:从步骤.原理 ...
随机推荐
- 基于 JMeter API 开发性能测试平台
背景: JMeter 是一个功能强大的性能测试工具,若开发一个性能测试平台,用它作为底层执行引擎在合适不过.如要使用其API,就不得不对JMeter 整个执行流程,常见的类有清楚的了解. 常用的 JM ...
- 如何调用API接口获取商品数据
在当今数字化的时代,电子商务的崛起使得网购成为了人们生活中不可或缺的一部分.作为电子商务中最为熟知和流行的平台之一,拥有大量的商品资源和用户群体.如果你是一名开发者或者是对数据分析感兴趣的人,你可能会 ...
- Python+Flask接口实现简单的ToKen功能
话不多说,上代码 from flask import request, jsonify from functools import wraps class TokenRequired: @classm ...
- Azure Data Factory(九)基础知识回顾
一,引言 在本文中,我们将继续了解什么是 Azure Data Factory,Azure Data Factory 的工作原理,Azure Data Factory 数据工程中的数据管道,并了解继承 ...
- 多租户基于Springboot+MybatisPlus实现使用一个数据库一个表 使用字段进行数据隔离
多租户实现方式 多租户在数据存储上主要存在三种方案,分别是: 1. 独立数据库 即一个租户一个数据库,这种方案的用户数据隔离级别最高,安全性最好,但成本较高. 优点:为不同的租户提供独立的数据库,有助 ...
- C#学习笔记--变量类型的转换
变量类型的转化: 转换原则 同类型的大的可以装小的,小类型的装大的就需要强制转换. 隐式转换: 同种类型的转换: //有符号 long-->int-->short-->sbyte l ...
- Eolink Apikit 如何进行自动化测试?
自动化测试是一种软件测试方法,利用自动化工具和脚本来执行测试用例,以验证软件应用程序的功能.性能.稳定性等特性.自动化测试的主要目的是提高测试效率.减少测试成本,并确保软件的质量和可靠性. 作为测试人 ...
- Visible Lattice Points 题解
Visible Lattice Points 题目大意 给定一个 \(N×N×N\) 的由若干点组成的立方体,点的坐标从 \((0,0,0)\) 到 \((N,N,N)\),求从点 \((0,0,0) ...
- Android dumpsys介绍
目录 一.需求 二.环境 三.相关概念 3.1 dumpsys 3.2 Binder 3.3 管道 四.dumpsys指令的使用 4.1 dumpsys使用 4.2 dumpsys指令语法 五.详细设 ...
- 广义 SAM 学习笔记
开 CF 开到了一道广义 SAM,决定来学一学. 发现网上确实充斥着各种各样的伪广义 SAM,也看到了前人反复修改假板子的过程,所以试着来整理一下这堆奇奇怪怪的问题. 当然本文的代码也不保证百分百正确 ...