date pg 为何没有时区_从Spring boot接口接收Date类型报错问题说开去

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

1、问题描述

1c03e41a8b7d9c35d2489ce1ec943f35.png

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

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

249da79d882e5b62cbd06ed86e8aa7fe.png

接口出错异常

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

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

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

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

03e95020adae38b0ca4a9cb6306a74ba.png

关键的GenericConversionService类

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

e36ed4848d862c7b2a774d7abd4c89a3.png

默认注册的类型转换器

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

f5933b758b7e53fafa9954bbf1dfe9b9.png

ObjectToObjectConverter转换器

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

23a7254aa052bca60bf96f6ff0af6c6d.png
35d6c81969a6be17879aa341e2d553d0.png

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

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

ctor.newInstance(source);

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

3、问题解决

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

一是懒办法

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

10e0f3e4d7115b01764043f239bf5914.png

Date(String s)源码

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

3373af06b14d8725f9e182be5049b036.png

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时,需要注意时区的问题!

二是主动出击

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

37f7412f008e52188aeb2ed6af2f57ca.png

自定义转换器

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

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

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

a5fb77dbd9e52f3354bb23cd5668a80f.png

注册转换器

4、注入RequestMappingHandlerAdapter

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

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


435a3120669ef6bf15749fcef050e074.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值