当前位置:首页 > 技术分析 > 正文内容

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

灾难:

某日,生产环境,有一接口,也不知道是恶意请求还是故意请求,日期时间传入字符串"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的回答:

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


#头条创作挑战赛#

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/3958.html

分享给朋友:

“spring + mysql, 日期年份大于9999带来的灾难” 的相关文章

gitlab简单搭建与应用

一、gitlab1、简介GitLab是利用Ruby on Rails一个开源的版本管理系统,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目。与Github类似,GitLab能够浏览源代码,管理缺陷和注释。可以管理团队对仓库的访问,它非常易于浏览提交过的版本并提供一个文件历...

GitLab 14.6发布,优化Geo高可用,安全更新等

昨天,GitLab官方按照管理发布了有一个月度版本GitLab 14.6的发布,这也是本年度收官版本。14.6中在安全合规性方面,在Geo方面以及MD代码块一键复制等方便做了优化,另外还在UI图标方面发布了一套全新的图标。详细情况请和虫虫一起学习。GitLab 14.6主要改进使用 Geo 实现无缝...

neovim 0.9在win下配置 python开发环境

初级的一些配置点击下面链接查看neovim安装插件管理器neovim常用快捷键neovim python开发环境简易配置方法 (需要手动键入命令行 运行python)安装neovim python的模块pip install pynvim pip install jedi pip install n...

深度解析!AI智能体在To B领域应用,汽车售后服务落地全攻略

在汽车售后服务领域,AI智能体的应用正带来一场效率和专业度的革命。本文深度解析了一个AI智能体在To B领域的实际应用案例,介绍了AI智能体如何通过提升服务顾问和维修技师的专业度及维修效率,优化汽车售后服务流程。上周我分享了AI智能体+AI小程序To C的AI应用场景《1000%增长!我仅用一个小时...

别让“跑焦”毁所有!仅需这一项设置,即可显著改善镜头对焦精度

我常常会收到一些摄影爱好者的私信,也一直在努力的帮助大家解决更多摄影中常见问题。在我收到的所有问题中。有一个问题是最麻烦的,那就是“为什么我的图像看起来模糊?”。这个问题几乎每个人都遇到过,究其原因可以说是多种多样相对复杂。起初我一直认为是对焦问题所导致,也就有了我之前所写的“后按对焦”以及“对焦模...

Vue2的16种传参通信方式

前言先直入主题列出有哪些传参方式,下面再通过事例一一讲解。props(父传子)$emit与v-on (子传父)EventBus (兄弟传参).sync与update: (父子双向)v-model (父子双向)ref$children与$parent$attrs与$listeners (爷孙双向)pr...