本文是我的《学透Spring Boot》专栏的第16篇文章,了解更多请移步我的专栏:
Postnull的专栏《学透Spring Boot》
目录
遇到问题
日期格式的转换
实现需求
创建转换器
注册转换器
编写Controller
访问测试
存在的问题
解决问题
源码分析
总结
遇到问题
本着没有问题也要制造问题的学习态度,我们今天通过实现一个需求来学习Spring MVC的类型转换。
我们希望通过http请求的参数 month=4,到MVC接收时自动变成 month=四月份。
能不能实现呢?
当然可以,一般的做法是接收到参数month=1,然后再控制器中手动转换。
但是这样不够优雅,我们需要把手动变全自动。
日期格式的转换
其实当然可以,因为Spring MVC已经这么做了。
MVC可以自动把我们请求中的字符串的日期,变成Controller方法中的日期对象。
我们的controller接收到date变量时,会自动转成LocalDate对象
实现需求
Spring MVC实现日期类型的自动转换,是通过一个组件ConversionService,我们可以称之为类型转换器。
如果我们要如果要添加配置类型转换器,需要继承WebMvcConfigurer接口,然后注册我们自定义的转换器。
创建转换器
注册转换器
编写Controller
访问测试
大功告成!只要分2步即可
- 定义转换器
- 注册转换器
然后参数就会自动的转换了。
存在的问题
但是这种方式不是完美无缺的,有个致命的问题。
因为我们的转换器,它是全局有效的,也就是说把所有的string入参,都会走MonthConverter转换成月份。它只看参数,不看参数名!
所以另外一个接口
它也走MonthConverter,这不是我们预期的。整个应用所有的string变量,都转换成月份,这还得了呢
解决问题
既然,Spring MVC转换器关注的是参数类型,那我们把转出类型换成特殊类型即可。
定义一个专门的类型,作为接收参数类型
把转换器的转换结果类型变成我们自定义类
重构controller,把入参类型变成自定义类型
然后访问,没有问题
访问其它的接口,入参是String类型,也没有受到我们自定义转换器的影响
总结,转换器关注的是转换前后的类型,我们定制一个专门的转出类型,就不会影响其它的接口了。
源码分析
我们知道如何定义和使用转换器了。但我们还想在了解Spring Boot如何实现的。
启动类
启动时会配置类型转换服务
转换服务中会注册“转换器”和“格式器”
这个addConverts是不是有点眼熟,我们之前也需要手动注册转换器
debug,我们看看有哪些内置的转换器
其中就包含了我们自定义的转换器
总结
本文我们通过编写并注册自定义的转换器,实现了请求参数的自动转换。通过这个例子,我们可以很好的了解Spring MVC的类型转换机制。