SpringBoot 在响应客户端请求时,将提交的数据封装成对象时,使用了内置的转换器,也就是自动帮我们封装对象。当然,SpringBoot 也支持自定义转换器,我们只需要实现Converter接口的convert方法即可
下面是我创建的一个Dog类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Dog {
private String name;
private Integer age;
}
我想在Controller里面将提交的参数自动封装为Dog,这当然很简单,我们只需要将提交参数的名称设置为name和age就行了,但是如果我的提交方式是下面这样呢
参数名称就是Dog,很明显,默认的机制是不能够处理了。
我们在springboot中参数的转换,封装是通过转换器来实现的,下面我们来看一下
springboot自带了124个转换器,可以实现大部分的类型间的转换
下面我创建了一个Controller,想让提交的参数自动封装为Dog
@RestController
public class TestController {
@RequestMapping("/t1")
public String t1(Dog dog) {
System.out.println("Dog信息:" + dog);
return "success";
}
}
如果我们提交的格式是name=xxx,age=xxx,显然是可以自动封装的,但是如果我们想让提取的参数就是叫dog,属性用,隔开,如dog=旺财,1,表示狗的名字叫旺财,年龄是1岁,这样默认的转换器显然不能处理
我们要处理这种转换显然我们需要自定义转换器了,我们实现Converter接口的convert方法就行了
我们在配置类里面注入一个WebMvcConfigurer
然后通过实现里面的addFormatters方法进行注入
使用如下
@Configuration
public class WebConfig {
@Bean
public WebMvcConfigurer webMvcConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new Converter<String, Dog>() {
@Override
public Dog convert(String s) {
String[] strings = s.split(",");
return new Dog(strings[0], Integer.parseInt(strings[1]));
}
});
}
};
}
}
我们是通过FormatterRegistry的addConverter方法进行Converter的注入的,在Converter的convert里面写逻辑即可,下面再来提交一下
可以发现已经可以实现功能了。
简单说明一下为什么会这样,可以理解为在进行参数转换时,springboot会去查找是否存在String->XXX的转换器,这里就是String->Dog,我们自定义的转换器就是String->Dog,当然也就会使用这个转换器了,如果没有那么就是使用默认转换器进行转换,也就是Dog对象里面的属性进行匹配,查看是否存在name,age