1. 前言

最近在自测接口时,发现一个问题:字段类型定义的是Date,但接口返回值里却是时间戳(1744959978674),

而不是预期的2025-04-18 15:06:18。

private Date useTime;
{
"code": "200",
"message": "",
"result": [
{
"id": 93817601,
"useTime": 1744959978674
}
]
}

这种返回值,无法快速的知道是哪个时间,如果想知道时间对不对,还得找一个时间戳转换工具做下转换才能确定,非常不方便。

因此想让接口直接返回预期的2025-04-18 15:06:18格式。

刚开始,在字段上添加了@JsonFormat注解,发现没生效,返回的还是时间戳:

import com.fasterxml.jackson.annotation.JsonFormat;

@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date useTime;

然后,改成了@JSONField注解,发现生效了,达到了预期的结果:

import com.alibaba.fastjson.annotation.JSONField;

@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date useTime;
{
"code": "200",
"message": "",
"result": [
{
"id": 93817601,
"useTime": "2025-04-18 15:06:18"
}
]
}

那么问题来了,为啥@JSONField生效,@JsonFormat不生效?

2. 原因分析

默认情况下,Spring Boot使用的JSON消息转换器是Jackson的MappingJackson2HttpMessageConverter,核心依赖为:

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.11.3</version>
</dependency>

现在使用Jackson的@JsonFormat注解不生效,说明Spring Boot没有使用默认的MappingJackson2HttpMessageConverter

使用fastjson的@JSONField注解生效了,说明Spring Boot使用的是fastjson下的JSON消息转换器,也就是

FastJsonHttpMessageConverter,依赖为:

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>

那么怎么找到代码在哪配置的呢?

第一步,先在项目中全局搜索FastJsonHttpMessageConverter(Windows快捷键:Ctrl+Shift+F),不过大概率是搜索不到,因为

公司里的项目一般都继承自公司公共的xxx-spring-boot-starter。

第二步,连按2次Shift键搜索FastJsonHttpMessageConverter,然后查找该类的引用或者子类(子类很可能是公司底层框架中写的)。

然后,很可能会找到类似下面的代码:

@Configuration
public class FastJsonMessageConverterConfig {
@Bean
public HttpMessageConverters customConverters() {
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
return new HttpMessageConverters(new HttpMessageConverter[]{fastJsonHttpMessageConverter});
}
}

以上代码显式注册了一个FastJsonHttpMessageConverter,并通过HttpMessageConverters覆盖了默认的HTTP 消息转换器

(Jackson的MappingJackson2HttpMessageConverter),所以Spring MVC将只使用fastjson处理JSON序列化/反序列化。

这也是@JSONField生效,@JsonFormat不生效的根本原因。

3. 默认行为及全局配置

fastjson 1.2.36及以上版本,默认将日期序列化为时间戳(如1744959978674),如果要默认将日期序列化为yyyy-MM-dd HH:mm:ss

(如2025-04-18 15:06:18),需要启用WriteDateUseDateFormat特性:

@Configuration
public class FastJsonMessageConverterConfig {
@Bean
public HttpMessageConverters customConverters() {
FastJsonConfig fastJsonConfig = new FastJsonConfig();
// 启用日期格式化特性(禁用时间戳)
fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteDateUseDateFormat);
// 设置日期格式(不指定时,默认为yyyy-MM-dd HH:mm:ss,但即使与默认值一致,也建议明确指定)
fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss"); FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
return new HttpMessageConverters(new HttpMessageConverter[]{fastJsonHttpMessageConverter});
}
}

如果某个日期字段有特殊序列化要求,可以使用@JSONField注解灵活配置(该注解会覆盖全局配置):

import com.alibaba.fastjson.annotation.JSONField;

@JSONField(format = "yyyy-MM-dd")
private Date anotherUseTime;

注意事项:

修改全局配置需慎重,如果一个老项目,原来日期类型返回的都是时间戳,突然全部改为返回字符串,可能会造成调用方报错。

文章持续更新,欢迎关注微信公众号「申城异乡人」第一时间阅读!

【深度思考】自定义日期格式,为什么@JSONField生效,@JsonFormat不生效?的更多相关文章

  1. POI对Excel自定义日期格式的读取

    用POI读取Excel数据:(版本号:POI3.7) 1.读取Excel private List<String[]> rosolveFile(InputStream is, String ...

  2. poi中如何自定义日期格式

    1. poi的“Quick Guide”中提供了 “How to create date cells ”例子来说明如何创建日期单元格,代码如下: HSSFCellStyle cellStyle = w ...

  3. 【教程】Tomcat 的catalina.out 日志按照自定义日期格式进行切割

    本文简单介绍在使用cronolog对tomcat的日志进行自定义日期格式的切割,方便日志的整理和遇到问题日志的排查! 安装cronolog 安装cronolog的方法网上有很多,这里也简单的介绍一下. ...

  4. poi处理excel自定义日期格式

    poi读取excel自定义时间类型时,读取到的是CELL_TYPE_NUMERIC,即数值类型,这个时候如果直接取值的话会发现取到的值和表格中的值不一样,这时应该先判断值是否是时间或者日期类型再进行处 ...

  5. 【源码分析】FastJson全局配置日期格式导致@JSONField(format = "yyyy-MM-dd")注解失效

    出现的问题 我全局配置的时间格式是:yyyy-MM-dd HH:mm:ss @JSONField注解配置的时间格式是:yyyy-MM-dd 最终的返回结果是:yyyy-MM-dd HH:mm:ss 问 ...

  6. springMvc返回Json中自定义日期格式

    (一)输出json数据 springmvc中使用jackson-mapper-asl即可进行json输出,在配置上有几点: 1.使用mvc:annotation-driven 2.在依赖管理中添加ja ...

  7. java中使用poi导入导出excel文件_并自定义日期格式

    Apache POI项目的使命是创造和保持java API操纵各种文件格式基于Office Open XML标准(OOXML)和微软的OLE复合文档格式(OLE2)2.总之,你可以读写Excel文件使 ...

  8. json-lib date对象转json ,加入自定义日期格式处理

    import net.sf.json.JSONObject; import net.sf.json.JsonConfig; import net.sf.json.processors.JsonValu ...

  9. .Net Core WebApi返回的json数据,自定义日期格式

    基本上所有的人都在DateTime类型的字段,被序列化成json的时候,遇到过可恨的Date(1294499956278+0800):但是又苦于不能全局格式化设置,比较难受.以往的方式,要么使用全局的 ...

  10. ASP.Net Core 返回的json数据,自定义日期格式

    //代码位置:Startup.cs public void ConfigureServices(IServiceCollection services) { services.AddMvc() .Ad ...

随机推荐

  1. Nodejs 实现一个CRC16校验

    近日在开发一个数据平台,据说nodejs比较适合DIRT类型的程序,所以也搞了一把,虽然接收.转发及其报文解析等功能顺利的实现了,但是由于某些报文涉及到应答,故而需要CRC校验,也算是一个小坑吧,故而 ...

  2. RocketMQ实战—4.消息零丢失的方案

    大纲 1.全链路分析为什么用户支付完成后却没有收到红包 2.RocketMQ的事务消息机制实现发送消息零丢失 3.RocketMQ事务消息机制的底层实现原理 4.是否可以通过同步重试方案来代替事务消息 ...

  3. 构建强大算力基础,奠定AI时代基石!

    7月6日,2023世界人工智能大会在上海拉开序幕.由中国电信主办的"算网一体 融创未来"主题论坛也于当日在上海世博中心举行.上海市经济和信息化委员会副主任戎之勤.上海市金山区人民政 ...

  4. Markdown文件上传到博客图片处理

    Markdown文件上传到博客图片处理 在本地编写Markdown文章并准备上传到博客园时,经常会遇到的一个挑战是本地图片无法直接显示,因为它们存储在本地文件系统中.为了解决这个问题,有两种常见的策略 ...

  5. Ubuntu Linux部署DeepSeek(转载用于学习)

    合集 - DeepSeek(4) 1.Ubuntu Linux部署DeepSeek02-06 2.Windows11本地部署DeepSeek加速02-073.DeepSeek部署本地知识库02-084 ...

  6. 燕千云ITSM已支持DeepSeek对接!AI能力持续升级

    春节期间,DeepSeek火爆全网,引发热议,作为国产AI大模型的黑马,DeepSeek凭借独特的训练方法.先进的模型架构和强大的联网推理能力,正不断拓展AI技术的应用边界.其"快思考&qu ...

  7. C#下.NET配置文件使用(二)

    app.config 与 Settings.settings 用VC#创建一个GUI程序后,就会有一个 Settings.settings 文件. 一旦我们通过VC#给它添加值后,在工程目录下会生成一 ...

  8. ABB机器人IRB1600齿轮箱维修故障四大原因

    一.ABB机器人IRB1600齿轮箱齿轮磨损 齿轮磨损是IRB1600齿轮箱常见的故障.长时间的高速运转和负载作用会导致齿轮表面磨损,进而产生噪音和振动.维修时,需要对磨损的齿轮进行更换,同时检查相邻 ...

  9. 从零构建你的第一个RESTful API:HTTP协议与API设计超图解指南 🌐

    title: 从零构建你的第一个RESTful API:HTTP协议与API设计超图解指南 date: 2025/2/26 updated: 2025/2/26 author: cmdragon ex ...

  10. C#语法糖foreach语句和using语句联合使用

    foreach语句可以和using语句联合使用,比如你需要对多个相机设备进行一些设置,设置完就调用 Dispose() 释放相机资源, 这时可以这样写: 模拟的设备类: class Device : ...