利用Spring boot开发对于Java开发者来说是必备的开发框架,该框架自2014年发布1.0以来,经过6年多的发展,其体系变得越来越大,越来越复杂,对开发者来说Java开发变得越来越容易,因此,Java新手基于Spring boot开发基本都是CRUD,因此,当出现问题后,大量的时间被耗费在百度、StackOverflow查找答案,找到答案后就变成了拷贝粘贴,对于深层次原理和设计的研究越来越肤浅……

1、问题描述




springboot json日期格式_构造函数

GET接口接受Date作为输入参数



如果没有任何配置的话,请求应该是失败的,如下图所示:




springboot json日期格式_构造函数_02

接口出错异常



错误就是无法从String转成Date:

Failed to convert value of type 'java.lang.String' to required type 'java.util.Date'

2、通过源码分析问题所在

Spring boot中对于输入参数的转换,是通过一个叫GenericConversionService的类负责的,如下图:




springboot json日期格式_自定义_03

关键的GenericConversionService类



其中有一个关键的属性是Converters,这里就记录了所有注册的类型转换器:




springboot json日期格式_Java_04

默认注册的类型转换器



其中就有String到Date的转换器。那为什么还会出错呢?通过调试我们得知默认情况下String到Date调用的转换器是ObjectToObjectConverter:




springboot json日期格式_构造函数_05

ObjectToObjectConverter转换器



这个转换器实际是到了万不得已的情况才会调用的,它的实现实际上就是通过反射将输入的String作为Target(这里就是Date)的构造函数的输入参数,然后创建新对象的过程,具体代码如下:




springboot json日期格式_springboot json日期格式_06


springboot json日期格式_Java_07


1、通过sourceClass和targetClass标明了是从String到Date的转换

2、通过反射得到构造函数引用,然后调用:

ctor.newInstance(source);

这其中source就是我们输入的按字符串编码的日期,调用了Date(String)这个构造函数。所以我们就知道为什么会出错了?原因很简单,就是我们输入的格式Date不认,最终就爆出了开篇所说的异常信息。

3、问题解决

通过源码分析我们清晰的定位了问题所在,所以解决起来就得心应手了,方案可以有两个:

一是懒办法

就是什么也不改,针对问题,我们知道Date(String)这个构造函数对于日期的格式是有要求的,我们只要按要求改输入的格式就可以了,我们来看看Date的源码:


springboot json日期格式_Java_08

Date(String s)源码


可以得知,Date(String s)这个构造函数被标注了Deprecated,就是不建议使用了,不过没关系,只要没有真正移除就还能用[吐彩虹]。构造函数里调用了parse(s)方法,我们接着看:


springboot json日期格式_date pg 为何没有时区_09

Date中parse方法的注释


通过了解parse方法的注释,我们清晰的知道,该方法可以解析的时间格式有好几种:IETF标准日期格式、美国大陆时区的缩写等,具体来说以下格式都是认的:

December 17, 1995 03:24:00Sat, 12 Aug 1995 13:30:00 GMTSun Oct 25 11:54:38 CST 20202020/10/20 10:12:2310/20/2020 10:12:23

各位可以根据实际情况选用,特别需要注意的是如果用Sun Oct 25 11:54:38 CST 2020或Sat, 12 Aug 1995 13:30:00 GMT时,需要注意时区的问题!

二是主动出击

如果默认的格式我们不想用,或者无法满足要求,则可以自定义转换器,例如:


springboot json日期格式_构造函数_10

自定义转换器


1、创建一个实现Convert的转换器

2、定义我们自定义的日期格式:"yyyy-MM-dd HH:mm:ss.SSS",本例中,可以定义任意种格式;

3、实现convert接口方法,完成转换动作


springboot json日期格式_springboot json日期格式_11

注册转换器


4、注入RequestMappingHandlerAdapter

5、将我们自定义的转换器注册到Spring boot中

至此,问题得到完美解决!



springboot json日期格式_date pg 为何没有时区_12