在 Spring MVC 框架中,对于常用的数据类型,有许多内置的类型转换器用于完成常用的类型转换。类型转换是在视图与控制器相互传递数据时发生的。Spring MVC 框架对于基本类型(例如 int、long、float、double、boolean 以及 char 等)已经做好了基本类型转换。对于引用数据类型,springMVC框架也可以将表单数据封装为该类型的属性值。
但是,在有些需求中,Spring MVC框架内置的类型转换器是不能满足需求的。比如:在进行动态条件查询时,可能需要将日期、整型等数据进行类型转换。
在以上需求中,可以按生日时间段、以及工资时间段查询员工信息。在Controller控制器中,我们应该用LocalDate、和Integer来接收客户端表单数据。这里需要注意,在Controller中,最好用 Integer包装类接收数据,不要用int。这是因为包装类允许为null,但int 不允许为null。这样可以根据Integer是否为null,来判断是否有这个条件。
不过,由于是动态条件查询,所以,对于文本框的数据用户是可以输入,也可以不输入的。这样一来,如果在生日文本框中没有输入数据,提交给服务器的数据为空字符串:""。如果使用springMVC默认的类型转换器,就会抛出转换异常:无法将""转换为日期类型。同样,springMVC默认的类型转换器,也无法将""转换为Integer类型。
当 Spring MVC 框架内置的类型转换器不能满足需求时,开发者可以开发自己的类型转换器。由开发者自定义的类型转换器,来告诉springMVC的转换规则。
在Spring MVC 框架中,提供 Converter<S,T> 接口,该接口可以定义一种数据类型转换成另一种数据类型的算法。这里 S 表示源类型,T 表示目标类型。如果开发者需要自定义类型转换器,只需要实现Converter接口,重写convert方法就可以了。
日期类型转换器:
public class LocalDateTypeChange implements Converter<String, LocalDate> {
@Override
public LocalDate convert(String s) {
//如果表单数据不为null,并满足指定格式时,进行类型转换
if(s != null && s.matches("\\d{4}-\\d{2}-\\d{2}")){
return LocalDate.parse(s);
}
//当表单数据为空,或格式不合法时,则返回null
return null;
}
}
Integer类型转换器:
public class IntegerTypeChange implements Converter<String,Integer> {
@Override
public Integer convert(String s) {
//如果表单数据不为null,并满足指定格式时,进行类型转换
if(s != null && s.matches("\\d+")){
return Integer.parseInt(s);
}
//当表单数据为空,或格式不合法时,则返回null
return null;
}
}
自定义转换器类写好了以后,必须要注册才能被springMVC容器所识别。这样当请求参数是匹配自定义类型转换器指定的数据类型时,springMVC就不再使用默认的类型转换器,而使用开发者自定义的类型转换器。
这里,我们采用内置tomcat整合springMVC的配置。注册springMVC自定义类型转换器时,需要在配置类中,添加以下代码:
@Configuration
@EnableWebMvc
@ComponentScan(basePackageClasses = WebApplicationConfig.class)
public class WebApplicationConfig implements WebMvcConfigurer {
@Autowired
private RequestMappingHandlerAdapter adapter;
//注册类型转换器
@PostConstruct
public void addConversionConfig() {
ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer) adapter
.getWebBindingInitializer();
if (initializer.getConversionService() != null) {
GenericConversionService converService = (GenericConversionService) initializer.getConversionService();
//注册转换器类
converService.addConverter(new LocalDateTypeChange());
converService.addConverter(new IntegerTypeChange());
}
}
}
注册完成以后,自定义类型转换器就生效了。在应用控制器中,书写代码测试一下:
@RestController
public class CarController {
@RequestMapping("typeChange")
public String typeChange(
LocalDate startDate,LocalDate endDate,
Integer startMoney,Integer endMoney){
System.out.println( "起始日期:" + startDate + " 结束日期:"+endDate
+ "起始工资:" + startMoney + " 结束工资:"+endMoney);
return "ok";
}
}
启动服务器,打开浏览器,在浏览器地址栏中输入:
http://localhost:8088/typeChange?startDate=&endDate=1995-09-10&startMoney=&endMoney=10000
在服务器控制台,可以看到打印的结果:
起始日期:null 结束日期:1995-09-10 起始工资:null 结束工资:10000
可以看到,当表单数据不满足指定格式时,得到null。表单数据满足指定格式时,才进行类型转换。
springMVC自定义类型转换器,除了可以对JDK已有的类型进行转换以外,也可以对自定义的实体类、集合等进行转换,实现方式大同小异。