当我们在提交表单过程中,我们提交的数据无法被转换为好数据时,就会需要自定义转换器了
如上所示,当我们向这样提交数据时,这没什么问题,springboot已经将一些基本的数据类型转换给我们自动添加了
可以看到,我们什么都不用干,就已经有这么多转换器了,
但是如果遇到下面的这种情况;
这样的话,springboot就没办法帮到我们了,因为Pet这个类型springboot压根就不知道,这种现定义的类型都没办法帮咱封装起来
没办法,咱只有自己定义了,那么,问题来了:如何定义才能让springboot认识呢?首先就得先观察springboot中自动注入的转换器是怎么运行的。
//来自TypeConverterDelegate.java publicT convertIfNecessary(@Nullable String propertyName, @Nullable Object oldValue, @Nullable Object newValue, @Nullable Class requiredType, @Nullable TypeDescriptor typeDescriptor) throws IllegalArgumentException { // Custom editor for this type? PropertyEditor editor = this.propertyEditorRegistry.findCustomEditor(requiredType, propertyName); ConversionFailedException conversionAttemptEx = null; // No custom editor but custom ConversionService specified? ConversionService conversionService = this.propertyEditorRegistry.getConversionService(); if (editor == null && conversionService != null && newValue != null && typeDescriptor != null) { TypeDescriptor sourceTypeDesc = TypeDescriptor.forObject(newValue); if (conversionService.canConvert(sourceTypeDesc, typeDescriptor)) { try { return (T) conversionService.convert(newValue, sourceTypeDesc, typeDescriptor); }
1、从源码可以发现,开始会获得一个conversionService对象,那么这玩意是干什么的呢,这个东西就是相当于一个封装器,它里面封装了所有的转换器,上面的截图中可以找到这个conversionService,
2、**canConvert()**判断是否能够转换,也就是判断有没有能转换我们需要的机器
3、conversionService.convert():这就是转换的主要方法
如果想要获取所有的转换器,springboot是这样做的:
ConversionService conversionService = this.propertyEditorRegistry.getConversionService();
所以说我们只需要把我们自定义的转换器注册进去就行了,但是不巧的是,需要的类无法使用
//不难发现,该类没有定义为public,所以我们也无法通过这个方法注入自定义的转换器
class TypeConverterDelegate {
private static final Log logger = LogFactory.getLog(TypeConverterDelegate.class);
private final PropertyEditorRegistrySupport propertyEditorRegistry;
@Nullable
private final Object targetObject;
理论上可以看它的上级,
也就是,查找那个类中封装了TypeConverterDelegate类,作为其属性,但不巧的是没找到,
所以就得找其他办法
springboot不是有一个自动配置类吗
WebMvcAutoConfiguration.java,我们可以在里面找找灵感
于是就发现了WebMvcConfigurer类,其中有一个方法可以实现我们想要的结果
default void addFormatters(FormatterRegistry registry) {
}
英文翻译就是说,可以添加转换器和格式器
所以就是他了
然后再咱的配置类中添加对应的组件
package com.boot.config;
import com.boot.pojo.People;
import com.boot.pojo.Pet;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.import;
import org.springframework.core.convert.converter.Converter;
import org.springframework.format.FormatterRegistry;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.util.UrlPathHelper;
//
@Configuration()
public class MyConfig {
@Bean
public WebMvcConfigurer webMvcConfigurer(){
return new WebMvcConfigurer() {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new Converter() {
@Override
public Pet convert(String source) {
if (!StringUtils.isEmpty(source)){
String[] split = source.split(",");
Pet pet = new Pet();
pet.setName(split[0]);
pet.setAge(Integer.parseInt(split[1]));
return pet;
}
return null;
}
});
}
};
}
}
可以发现我们的转换器已经注入进去了



