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. AI编程助手带来的洞察和启发——程序员职业的变革

    前言 从chatgpt的横空出世到国内大模型的强势崛起, 从AI只会写诗作画到辅助编程, AI作为新质生产力的重要角色逐渐进入各行各业,为行业带来新的可能性. Cursor.通义灵码这类"A ...

  2. idea遇见Command line is too long. Shorten command line for Main or also for Application default configuration?

    <property name="dynamic.classpath" value="true" /> 第一步:找到项目目录下的.idea\works ...

  3. 大模型背后的向量魔法:Embedding技术初探

    本文原本是2022年写的,然而一直没有完善,自从LLM火起来之后,NLP领域的技术更新很快,本文只是大概介绍了Embedding相关的基础知识,具体应用接下来会在博客更新发布. 前言 又是很长一段时间 ...

  4. DeepSeek-R1本地部署如何选择适合你的版本?看这里

    DeepSeek-R1本地部署:选择最适合你的版本,轻松搞定! 关于本地部署DeepSeek-R1前期知识 如果你正在考虑将DeepSeek-R1部署到本地服务器上,了解每种类型的硬件需求是非常重要的 ...

  5. SHA1字符串加密

    使用SHA1算法,生成某个字符串的hash值作为该字符串所代表对象的唯一标识: Demo: using System; using System.Collections.Generic; using ...

  6. WPF 创建自定义鼠标光标指针

    WPF Cursor类中的两个构造函数: public Cursor(Stream cursorStream) public Cursor(string cursorFile) 以上的构造函数所使用的 ...

  7. QT5笔记:36. QGraphicsView 综合示例 (完结撒花!)

    通过此示例可以比较熟悉QGraphincsView的流程以及操作 坐标关系以及获取: View坐标:左上角为原点,通过鼠标移动事件获取 Scene坐标:中心为原点,横竖为X,Y轴.通过View.map ...

  8. mybatis - [13] 分页

    题记部分 001 || limit select * from mybatis.user limit 2,5; 2代表偏移量,从结果集的第3行开始. 5代表返回的记录数 UserMapper List ...

  9. 淘宝 NPM 镜像站

    应该有不少开发者已经发现,访问淘宝 NPM 已经会自动 301 跳转到 npmmirror.com 新域名,这是我们独立注册和备案的域名. Web 站点:https://npmmirror.com R ...

  10. 面试题10- II. 青蛙跳台阶问题

    地址:https://leetcode-cn.com/problems/qing-wa-tiao-tai-jie-wen-ti-lcof/ <?php /** 一只青蛙一次可以跳上1级台阶,也可 ...