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. shell 数组函数进阶练习

    一维数组的定义.统计.引用和删除等操作. A=( test1 test2 test3 ) ,定义数组一般以括号的方式来定义, 数组的值可以随机定义. echo ${A[0]} ,代表引用第一个数组变量 ...

  2. 干货:DeepSeek+SpringAI实现流式对话!

    前面一篇文章我们实现了<炸裂:SpringAI内置DeepSeek啦!>,但是大模型的响应速度通常是很慢的,为了避免用户用户能够耐心等待输出的结果,我们通常会使用流式输出一点点将结果输出给 ...

  3. 8款支持 C# 语言的 AI 辅助编程神器,高效编程利器!

    前言 在当今这个AI技术日新月异的时代,一股创新的浪潮正席卷着软件开发领域,其中AI辅助编程工具以其独特的魅力脱颖而出,成为了众多开发者不可或缺的得力助手.这些工具不仅能够显著提升开发效率,优化代码质 ...

  4. 【译】HTTP 文件更新了请求变量

    许多用户都要求在 Visual Studio 的 HTTP 文件中添加对请求变量的支持.使用请求变量,您可以发送 HTTP 请求,然后在从 HTTP 文件发送的任何后续请求中使用响应或请求中的数据.我 ...

  5. Thymeleaf遍历选中多个复选框

    使用场景:用户角色一对多关联关系 <!-- roleList:所有角色信息 :userRoleList:用户已有角色id列表--> <input th:each="role ...

  6. 【软件开发】Git 概念与常用命令

    [软件开发]Git 概念与常用命令 Git 概念 存储方式 Git 是分布式存储,每一个 clone 下来的仓库都可以看成独立的个体,只是 Git 有提供同步功能,因此 Git 支持离线使用,因为本质 ...

  7. 饥荒联机版 mod

    Extra Equip Slots Extra Equip Slots 额外装备槽:护甲.背包.护符各用各的插槽 Wormhole Marks [DST] Wormhole Marks DST] 相通 ...

  8. C++17 Filesystem 实用教程

    点击查看代码 C++17 标准带来了 std::filesystem库, 提供了强大的工具来处理文件路径, 目录以及其他与文件系统相关的操作. 这篇文章适合 C++ 初学者以及希望掌握 C++17 新 ...

  9. Qt个人项目总结 —— MySQL数据库查询与断言

    3.Qt项目总结--数据库查询断言问题 问题: 当我使用MySQL数据库的查询操作时, 如果查询的数据在数据库中不存在,那么Qt会直接被干崩溃 但是?为什么呢?不应该是返回if语句中的结果吗,为什么会 ...

  10. Ubuntu20.04搭建k8s v1.23.3版本集群

    前言 服务器统一版本 Ubuntu 20.04 搭建集群最少要两台服务器 每台服务器都需要 docker.环境配置.安装 kubeadm.kubelet 和 kubectl docker 安装 doc ...