Python 官方文档:入门教程 => 点击学习
目录前言1、响应JSON数据:Jackson.jar+@ResponseBody2、原理解析3、内容协商3.1、概述3.2、postman分别测试返回json和xml3.3、开启浏览
响应页面指的是我们如何发送一个请求,跳转到指定页面。将会在后面的视图解析中说明。 响应页面常见于开发单体应用。 响应数据常见于开发前后端分离的应用。后端代码主要用来接收请求。前端页面给我们发送过来请求,给前端响应json数据。或者给前端响应xml、图片、音视频数据。
在前后端分离开发过程中,后端一般会将数据集封装成一个JSON对象响应给前端 ,一般只需要标准ResponseBody即可给前端返回数据
假设给前端自动返回json数据,需要引入相关的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-WEB</artifactId>
</dependency>
<!-- web场景自动引入了json场景 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
<version>2.3.4.RELEASE</version>
<scope>compile</scope>
</dependency>
控制层代码如下:引入了依赖后,给方法上标注@ResponseBody,就可以给前端自动返回JSON数据。
@Controller
public class ResponseTestController {
@ResponseBody //原理就是利用返回值处理器里面消息转换器进行处理
@GetMapping("/test/person")
public Person getPerson(){
Person person = new Person();
person.setAge(28);
person.setBirth(new Date());
person.setUserName("zhangsan");
return person;
}
}
测试:
SpringMVC到底支持哪些返回值
HTTPMessageConverter原理
MessageConverter规范
HttpMessageConverter:看是否支持将 此 Class类型的对象,转为MediaType类型的数据。 例子:CanWrite将Person对象转为JSON。canRead或者 JSON转为Person
默认的MessageConverter
最终 MappingJackson2HttpMessageConverter 把对象转为JSON(利用底层的jackson的objectMapper转换的)
根据客户端接收能力不同【有的只接收xml,有的只接收json】,返回不同媒体类型的数据。比如返回xml数据给前
引入支持XML依赖:
<dependency>
<groupId>com.fasterxml.jackson.datafORMat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
重新编译该项目运行 ,返回了xml数据
在上面的测试中,此时如果我用postman发送相同的请求,则得到的是json数据,为啥同样的请求,方式不一样,返回的数据不一样呢。原因就是请求头中规定的数据响应先后顺序
查看请求头
内容协商Accept中,浏览器具备什么类型数据的接收能力,可以看到xml数据是优先被接收的。
可用Postman软件分别测试返回json和xml:只需要改变请求头中Accept字段(application/json、application/xml)。Http协议中规定的,告诉服务器本客户端可以接收的数据类型。
为了方便内容协商,开启基于请求参数的内容协商功能。
spring:
contentneGotiation:
favor-parameter: true #开启请求参数内容协商模式
发请求:
确定客户端接收什么样的内容类型;
1、Parameter策略优先确定是要返回json数据(获取请求头中的format的值) 2、最终进行内容协商返回给客户端json即可。
导入了jackson处理xml的包,xml的converter就会自动进来
WebmvcConfigurationSupport
jackson2XmlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", classLoader);
if (jackson2XmlPresent) {
Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.xml();
if (this.applicationContext != null) {
builder.applicationContext(this.applicationContext);
}
messageConverters.add(new MappingJackson2XmlHttpMessageConverter(builder.build()));
}
实现多协议数据兼容。json、xml、x-guigu
要自定义SpringMVC的什么功能,即通过一个入口给容器中添加一个 WebMvcConfigurer
假设你想基于自定义请求参数的自定义内容协商功能。换句话,在地址栏输入http://localhost:8080/test/person?format=gg返回数据,跟http://localhost:8080/test/person且请求头参数`Accept:application/x-guigu`的返回自定义协议数据的一致。
演示
通过上文分析,我们只需要实现WebMvcConfigurer接口,并实现了configureMessageConverters方法,就可以达到自定义消息转换器的目的。例如,我不想用jackson了,想用fastjson的消息转换器,我们可以添加fastjson相关的MessageConverter就可以了
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
List<MediaType> fastMediaTypes = new ArrayList<>();
fastMediaTypes.add(MediaType.TEXT_html);
fastMediaTypes.add(MediaType.APPLICATION_JSON);
fastConverter.setSupportedMediaTypes(fastMediaTypes);
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(
SerializerFeature.WriteMapNullValue,
SerializerFeature.WriteNullStringAsEmpty,
SerializerFeature.WriteNullListAsEmpty,
SerializerFeature.WriteDateUseDateFormat);
SerializeConfig serializeConfig = SerializeConfig.globalInstance;
serializeConfig.put(BigInteger.class, ToStringSerializer.instance);
serializeConfig.put(Long.class, ToStringSerializer.instance);
serializeConfig.put(Long.TYPE, ToStringSerializer.instance);
fastJsonConfig.setSerializeConfig(serializeConfig);
fastConverter.setFastJsonConfig(fastJsonConfig);
converters.add(fastConverter);
}
}
测试
@Data
public class Person {
private String userName;
private Integer age;
//使用fastjson的注解进行转换
@JSONField(format = "yyyy-MM-dd")
private Date birth;
private Pet pet;
}
除此之外,这些都是默认的,我们可以进行扩展,如下实现自定义的设置转化,如下,利用这个代码:
@Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
}
}
}
测试
@Configuration(proxyBeanMethods = false)
public class WebConfig {
@Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new GuiguMessageConverter());
}
}
}
}
public class GuiguMessageConverter implements HttpMessageConverter<Person> {
@Override
public boolean canRead(Class<?> clazz, MediaType mediaType) {
return false;
}
@Override
public boolean canWrite(Class<?> clazz, MediaType mediaType) {
return clazz.isAssignableFrom(Person.class);
}
@Override
public List<MediaType> getSupportedMediaTypes() {
return MediaType.parseMediaTypes("application/x-guigu");
}
@Override
public Person read(Class<? extends Person> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
return null;
}
@Override
public void write(Person person, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
//自定义协议数据的写出
String data = person.getUserName()+";"+person.getAge()+";"+person.getBirth();
//写出去
OutputStream body = outputMessage.getBody();
body.write(data.getBytes());
}
}
测试:
import java.util.Date;
@Controller
public class ResponseTestController {
@ResponseBody //利用返回值处理器里面的消息转换器进行处理
@GetMapping(value = "/test/person")
public Person getPerson(){
Person person = new Person();
person.setAge(28);
person.setBirth(new Date());
person.setUserName("zhangsan");
return person;
}
}
日后开发要注意,有可能我们添加的自定义的功能会覆盖默认很多功能,导致一些默认的功能失效。
到此这篇关于Spring Boot数据响应问题的文章就介绍到这了,更多相关SpringBoot数据响应内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: Spring Boot数据响应问题实例详解
本文链接: https://www.lsjlt.com/news/142414.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0