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,协商,请求,import,机制,com,客户端
From: https://www.cnblogs.com/ybbit/p/17498483.html