文章目录
-
- 1.自定义转换器
-
-
- 1.代码实例
-
- 1.save.html
- 2.编写两个bean
- [3.WebConfig.java 配置类来自定义转换器](#3.WebConfig.java 配置类来自定义转换器)
- 4.测试
- 2.注意事项和细节
-
- 2.处理Json
- 3.内容协商
-
-
- 1.基本介绍
- 2.应用实例
- 3.debug当Accept是xml时的源码
-
- [1.ctrl + n 找到AbstractJackson2HttpMessageConverter](#1.ctrl + n 找到AbstractJackson2HttpMessageConverter)
- 2.下断点
- 3.debug启动
- 4.直接跳到关键部分
- 5.再跳一下
- 4.使用浏览器发送请求分析
- 5.SpringBoot开启基于内容协商的功能
- 6.内容协商总结
-
1.自定义转换器
1.代码实例
1.save.html
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/save" method="post">
编号: <input name="id" value="100"><br/>
姓名: <input name="name" value="牛魔王"/> <br/>
年龄: <input name="age" value="120"/> <br/>
婚否: <input name="isMarried" value="true"/> <br/>
生日: <input name="birth" value="2000/11/11"/> <br/>
<!--使用自定义转换器来关联acr,字符串整体提交,使用,间隔-->
坐骑: <input name="car" value="大白熊,666.6"><br>
<input type="submit" value="保存"/>
</form>
</body>
</html>
2.编写两个bean
1.Car.java
java
package com.sun.springboot.bean;
import lombok.Data;
/**
* @author 孙显圣
* @version 1.0
*/
@Data
public class Car {
private String name;
private Double price;
}
2.Monster.java
java
package com.sun.springboot.bean;
import lombok.Data;
import java.util.Date;
/**
* @author 孙显圣
* @version 1.0
*/
@Data
public class Monster {
private Integer id;
private String name;
private Integer age;
private Boolean isMarried;
private Date birth;
private Car car;
}
3.WebConfig.java 配置类来自定义转换器
java
package com.sun.springboot.config;
import com.sun.springboot.bean.Car;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.format.FormatterRegistry;
import org.springframework.util.ObjectUtils;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author 孙显圣
* @version 1.0
*/
@Configuration(proxyBeanMethods = false) //启动Lite模式,则注入的bean对象必须通过该配置类的bean对象来获取才能生效,所有的bean都是多例
public class WebConfig {
//注入多例bean WebMvcConfigurer
@Bean
public WebMvcConfigurer webMvcConfigurer() {
//1.使用匿名内部类来实现WebMvcConfigurer接口的方法,并返回对象
return new WebMvcConfigurer() {
@Override
//2.实现addFormatters方法
public void addFormatters(FormatterRegistry registry) {
//3.调用addConverter方法,然后使用匿名内部类实现Converter接口的方法,里面的泛型就是从什么类型转换到什么类型
registry.addConverter(new Converter<String , Car>() {
@Override
public Car convert(String s) { //这个s就是传进来的数据String类型的
//4.这里加入自定义的业务转换代码
//判断是否为空
if (!ObjectUtils.isEmpty(s)) {
//分割字符串
String[] split = s.split(",");
//创建一个Car,并赋值
Car car = new Car();
car.setName(split[0]);
car.setPrice(Double.parseDouble(split[1]));
return car;
}
//这里如果是空就返回一个null
return null;
}
});
//5.在这里还可以继续registry.addConverter()添加转换器
}
};
}
}
4.测试
2.注意事项和细节
1.debug查看转换器总数
1.打断点
2.执行到断点后,选左边的192
3.可以看出,加上自定义的转换器一共125个
2.一次新增多个转换器
3.多个转换器的key重复的情况
- 由于存储转换器的类型为ConcurrentHashMap,key不可以重复
- 所以一旦定义了多个key相同的转换器则只会保留最后定义的,其余的会被替换
2.处理Json
1.需求分析
2.代码实现
java
package com.sun.springboot.controller;
import com.sun.springboot.bean.Monster;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Date;
/**
* @author 孙显圣
* @version 1.0
*/
@Controller
public class JsonController {
//返回json类型的Monster对象
@GetMapping("/getMonster")
@ResponseBody //将结果转换为json字符串并返回
public Monster monsterToJson() {
Monster monster = new Monster();
monster.setAge(1);
monster.setName("sun");
monster.setId(1);
monster.setCar(null);
monster.setBirth(new Date());
return monster;
}
}
3.测试
3.内容协商
1.基本介绍
2.应用实例
首先在pom.xml引入可以处理xml的依赖
xml
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
1.需求分析
2.使用postman测试,修改Accept为application/xml
3.返回的结果是xml类型
4.如果换成原来的任意类型
5.返回的结果是json类型
3.debug当Accept是xml时的源码
1.ctrl + n 找到AbstractJackson2HttpMessageConverter
2.下断点
3.debug启动
4.直接跳到关键部分
5.再跳一下
4.使用浏览器发送请求分析
5.SpringBoot开启基于内容协商的功能
1.需求分析
由于浏览器的Accept不能像postman一样修改,所以,只能根据浏览器默认的权重来决定数据的返回类型
比如:由于浏览器的Accept中xml的权重很高,那就意味着如果后端引用了可以处理xml的依赖,那么后端
就只能给前端返回xml类型的数据,非常不灵活
2.开启基于内容协商的功能 application.yml
yaml
spring:
mvc:
contentnegotiation:
favor-parameter: true
3.具体使用
6.内容协商总结
- 添加了**@ResponseBody**之后,该接口就可以与浏览器进行内容协商
- 会根据浏览器的Accept的权重来决定优先返回什么类型的数据
- 由于浏览器的Accept不够灵活,所以可以在SpringBoot中开启基于内容协商的功能,这样只需要在网址后面加上format参数即可决定要返回的类型