基本介绍
1.SpringBoot在响应客户端请求时, 将提交的数据封装成对象时, 使用了内置转换器
2.SpringBoot也支持自定义转换器, 这个内置转换器在debug
的时候, 可以看到, 提供了124
个内置转换器, 看下源码. GenericConverter类-ConvertiblePair(内部类)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n64zfgcT-1721040003162)(https://i-blog.****img.cn/direct/50b34f1225eb4971a8f3dba5bba7b470.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AI0JIntt-1721040003163)(https://i-blog.****img.cn/direct/27193c8fb918421d948762777329f940.png)]
应用实例
需求说明: 演示自定义转换器使用
1.修改save.html
<!--使用自定义转换器关联car, 字符串整体提交, 使用,号间隔-->
坐骑: <input name="name" value="碧水金睛兽,666.6"><br/
2.创建src/main/java/com/zzw/springboot/config/WebConfig.java
, 增加自定义转换器
springboot系列四: sprintboot容器功能
/**
* @Configuration(proxyBeanMethods = false)
* 1.表示 WebConfig 是一个配置类
* 2.proxyBeanMethods = false 表示使用Lite模式
*/
@Configuration(proxyBeanMethods = false)
public class WebConfig {
//注入bean WebMvcConfiger
@Bean
public WebMvcConfigurer webMvcConfigurer() {
//整个是WebMvcConfigurer接口的匿名内部类
return new WebMvcConfigurer() {
@Override
public void addFormatters(FormatterRegistry registry) {
/**
* 解读
* 1.在addFormatters方法中, 增加一个自定义转换器
* 2.增加自定义转换器 String -> Car
* 3.增加的自定义转换器会注册到 converters 容器中
* 4.converters 底层结构是 ConcurrentHashMap, 内置有124个转换器[不同版本个数不一样~]
* 5.一会我们debug查看这些转换器
*/
registry.addConverter(new Converter<String, Car>() {//传入Converter接口的匿名内部类
@Override
public Car convert(String source) {//source就是 传入的字符串 碧水金睛兽,666.6
//这里加入自定义的转换业务代码
if (!ObjectUtils.isEmpty(source)) {
String[] split = source.split(",");
Car car = new Car();
car.setVehicleName(split[0]);
car.setVehiclePrice(Double.parseDouble(split[1]));
return car;
}
return null;
}
});
}
};
}
}
3.测试
monster = Monster(id=100, name=张三, age=30, maritalStatus=false, birthday=Sat Jan 01 00:00:00 CST 1994, car=Car(vehicleName=碧水金睛兽, vehiclePrice=666.6))
查看源码
1.debug
, 可以看到我们新增的Converter
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nPqeHa29-1721040003163)(https://i-blog.****img.cn/direct/9c05a54db2244cb192a287f7d98dfce2.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9skR4MEM-1721040003164)(https://i-blog.****img.cn/direct/fec0688d49f046c6bc8d80573fde9053.png)]
快捷键查看有多少元素
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wR5q4B80-1721040003164)(https://i-blog.****img.cn/direct/9c79994680b44d28bc42a0bc0c159103.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HqZ2NF1q-1721040003164)(https://i-blog.****img.cn/direct/973caedb153249e7a1b70425eef87598.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xmAQCBcX-1721040003165)(https://i-blog.****img.cn/direct/3c6e6978aae644d080553e9b6dedd401.png)]
注意事项和细节
1.注册转换器换种写法, 方便理解
/**
* @Configuration(proxyBeanMethods = false)
* 1.表示 WebConfig 是一个配置类
* 2.proxyBeanMethods = false 表示使用Lite模式
*/
@Configuration(proxyBeanMethods = false)
public class WebConfig {
//注入bean WebMvcConfiger
@Bean
public WebMvcConfigurer webMvcConfigurer() {
//整个是WebMvcConfigurer接口的匿名内部类
return new WebMvcConfigurer() {
@Override
public void addFormatters(FormatterRegistry registry) {
/**
* 解读
* 1.在addFormatters方法中, 增加一个自定义转换器
* 2.增加自定义转换器 String -> Car
* 3.增加的自定义转换器会注册到 converters 容器中
* 4.converters 底层结构是 ConcurrentHashMap, 内置有124个转换器[不同版本个数不一样~]
* 5.一会我们debug查看这些转换器
*/
/*registry.addConverter(new Converter<String, Car>() {//传入Converter接口的匿名内部类
@Override
public Car convert(String source) {//source就是 传入的字符串 碧水金睛兽,666.6
//这里加入自定义的转换业务代码
if (!ObjectUtils.isEmpty(source)) {
String[] split = source.split(",");
Car car = new Car();
car.setVehicleName(split[0]);
car.setVehiclePrice(Double.parseDouble(split[1]));
return car;
}
return null;
}
});*/
//换种写法注册自定义转换器, 方便理解
//1.先创建一个自定义的转换器
Converter<String, Car> zzwConverter = new Converter<String, Car>() {//传入Converter接口的匿名内部类
@Override
public Car convert(String source) {//source就是 传入的字符串 碧水金睛兽,666.6
//这里加入自定义的转换业务代码
if (!ObjectUtils.isEmpty(source)) {
String[] split = source.split(",");
Car car = new Car();
car.setVehicleName(split[0]);
car.setVehiclePrice(Double.parseDouble(split[1]));
return car;
}
return null;
}
};
//添加转换器到converters容器
registry.addConverter(zzwConverter);
//还可以增加更多的转换器....
}
};
}
}
2.假如我们不添加自定义转换器, 会报typeMismatch
错误, 报400错误. 而400
错误是客户端的错误, 请求包含语法错误.
JavaWeb系列八: WEB 开发通信协议(HTTP协议)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D4ZOyjUN-1721040003165)(https://i-blog.****img.cn/direct/0130ecd4d2aa4422a3f432287e1cdd91.png)]
3.创建两个自定义转换器
/**
* @Configuration(proxyBeanMethods = false)
* 1.表示 WebConfig 是一个配置类
* 2.proxyBeanMethods = false 表示使用Lite模式
*/
@Configuration(proxyBeanMethods = false)
public class WebConfig {
//注入bean WebMvcConfiger
@Bean
public WebMvcConfigurer webMvcConfigurer() {
//整个是WebMvcConfigurer接口的匿名内部类
return new WebMvcConfigurer() {
@Override
public void addFormatters(FormatterRegistry registry) {
/**
* 解读
* 1.在addFormatters方法中, 增加一个自定义转换器
* 2.增加自定义转换器 String -> Car
* 3.增加的自定义转换器会注册到 converters 容器中
* 4.converters 底层结构是 ConcurrentHashMap, 内置有124个转换器[不同版本个数不一样~]
* 5.一会我们debug查看这些转换器
*/
/*registry.addConverter(new Converter<String, Car>() {//传入Converter接口的匿名内部类
@Override
public Car convert(String source) {//source就是 传入的字符串 碧水金睛兽,666.6
//这里加入自定义的转换业务代码
if (!ObjectUtils.isEmpty(source)) {
String[] split = source.split(",");
Car car = new Car();
car.setVehicleName(split[0]);
car.setVehiclePrice(Double.parseDouble(split[1]));
return car;
}
return null;
}
});*/
//换种写法注册自定义转换器, 方便理解
//1.先创建一个自定义的转换器
Converter<String, Car> zzwConverter = new Converter<String, Car>() {//传入Converter接口的匿名内部类
@Override
public Car convert(String source) {//source就是 传入的字符串 碧水金睛兽,666.6
//这里加入自定义的转换业务代码
if (!ObjectUtils.isEmpty(source)) {
String[] split = source.split(",");
Car car = new Car();
car.setVehicleName(split[0]);
car.setVehiclePrice(Double.parseDouble(split[1]));
return car;
}
return null;
}
};
//还可以增加更多的转换器....
//第2个自定义的转换器
Converter<String, Monster> zzwConverter2 = new Converter<String, Monster>() {
@Override
public Monster convert(String source) {
return null;
}
};
//添加转换器到converters容器
registry.addConverter(zzwConverter);
registry.addConverter(zzwConverter2);
}
};
}
}
debug, 看一看 converters容器 是不是变成了 126 个.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6Eo32GPY-1721040003166)(https://i-blog.****img.cn/direct/65d365997f984b26bf3e9a2267b72d07.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WEFtnsU6-1721040003166)(https://i-blog.****img.cn/direct/d2ca48c92c664208b106daa3e9ec59d4.png)]
4.创建三个自定义转换器, 由于key是[源类型->目标类型], 所以会覆盖掉一个.
//1.先创建一个自定义的转换器
Converter<String, Car> zzwConverter = new Converter<String, Car>() {//传入Converter接口的匿名内部类
@Override
public Car convert(String source) {//source就是 传入的字符串 碧水金睛兽,666.6
//这里加入自定义的转换业务代码
if (!ObjectUtils.isEmpty(source)) {
String[] split = source.split(",");
Car car = new Car();
car.setVehicleName(split[0]);
car.setVehiclePrice(Double.parseDouble(split[1]));
return car;
}
return null;
}
};
//还可以增加更多的转换器....
//第2个自定义的转换器
Converter<String, Monster> zzwConverter2 = new Converter<String, Monster>() {
@Override
public Monster convert(String source) {
return null;
}
};
//第3个自定义的转换器
Converter<String, Car> zzwConverter3 = new Converter<String, Car>() {
@Override
public Car convert(String source) {
return null;
}
};
//添加转换器到converters容器
registry.addConverter(zzwConverter);
registry.addConverter(zzwConverter2);
registry.addConverter(zzwConverter3);
1)测试, 是否覆盖.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tCQzI29s-1721040003167)(https://i-blog.****img.cn/direct/cf4a77912c5c4cdc9bbb14349ccf6ffc.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G63TxTQP-1721040003167)(https://i-blog.****img.cn/direct/bbcb6f8b0d714c3389a6c2ca75b96b7d.png)]
2)查看 converters 容器. 因为第三个转换器和第一个转换器 key 是相同的, 所以覆盖掉了.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ot1aXvcC-1721040003168)(https://i-blog.****img.cn/direct/5226ced93f7343b4a0383e0a727ec890.png)]