龙空技术网

spring + mysql, 日期年份大于9999带来的灾难

八斗九月 50

前言:

现在看官们对“mysql查询大于日期”可能比较关注,各位老铁们都想要了解一些“mysql查询大于日期”的相关内容。那么小编同时在网络上汇集了一些有关“mysql查询大于日期””的相关内容,希望大家能喜欢,朋友们一起来学习一下吧!

灾难:

某日,生产环境,有一接口,也不知道是恶意请求还是故意请求,日期时间传入字符串"20232023-08-03 11:23:07", MySQL时间索引失效,全表扫描,由于数据量比较大,当场宕机,绩效被扣,当场吐血,内心万马奔腾。

初一看,年份"20232023",多了一个"2023", 照理在spring中,会直接报一个异常:参数无效,格式无法转换。

细一想,年份"20232023",是一个合理的年份,只是我们活在了"2023"年,格局小了,忘了子孙后代有可能活在"20232023"年。

最后查了nginx的accesslog,并没发现有"20232023-08-03 11:23:07"的日志,不出意外,是内部开发写的程序,直接通过ip:port调用的。

那么,为什么在程序中使用了@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 和 @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")限定了请求报文的实体的时间格式,还能接受"20232023"? 请看下文。

问题代码:

这里说明一下:

代码中使用了@JsonFormat和@DateTimeFormat注解来定义日期格式,但在Spring中,这两个注解的作用域略有不同:

@JsonFormat:只会在序列化/反序列化Json时生效,也就是说只对从Json字符串转换为Java对象时有效@DateTimeFormat:会在任何日期转换时生效,包括从字符串转换为Date对象等

所以GET请求,传入的参数beginTime=20232023-08-03%2011:23:07&endTime=2023-08-03%2011:23:07,实际上是是通过@DateTimeFormat进行解析的,而不是@JsonFormat。@DateTimeFormat默认会使用一定的容错机制进行解析,这和Spring的日期转换操作一致。

尝试过添加以下配置项:

spring.mvc.format.date-time=yyyy-MM-dd HH:mm:ss

spring.mvc.format.date=yyyy-MM-dd

程序仍然能正常解析"20232023-08-03 11:23:07"

最后将请求报文实体的Date类型,改为LocalDateTime类型,满足了需求,即改为如下代码:

满足了我们的期望,传入参数beginTime=20232023-08-03%2011:23:07,返回异常:

参数无效:beginTime Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDateTime' for property 'beginTime'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@com.fasterxml.jackson.annotation.JsonFormat @org.springframework.format.annotation.DateTimeFormat java.time.LocalDateTime] for value '20232023-08-03 11:23:07'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [20232023-08-03 11:23:07]

for why:

为什么在@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")注解下Date类型能解析"20232023-08-03 11:23:07",而LocalDateTime类型不能解析"20232023-08-03 11:23:07"?

Date类型中的year用的是int类型,而LocalDateTime类型中的year用的是long类型,不应该支持的年份范围更广吗?

看下ai claude的回答:

看下ai claude2的回答:

再看下chatgpt的回答:

总感觉回答不对,有没有大神知道的,欢迎在评论区中指点一二。

#头条创作挑战赛#​

标签: #mysql查询大于日期