1. Preface
Recently, when I was testing the interface, I found a problem: the field type defines Date, but the return value of the interface is a timestamp (1744959978674).
Instead of the expected 2025-04-18 15:06:18.
private Date useTime;
{
"code": "200",
"message": "",
"result": [
{
"id": 93817601,
"useTime": 1744959978674
}
]
}
This kind of return value cannot be quickly known which time it is. If you want to know whether the time is right, you have to find a timestamp conversion tool to down-convert it, which is very inconvenient.
Therefore, I want the interface to directly return to the expected 2025-04-18 15:06:18 format.
At the beginning, I added it to the field@JsonFormat
The annotation is found to be ineffective, and the time stamp is returned:
import ;
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date useTime;
Then, it was changed to@JSONField
The annotation was found to take effect and achieved the expected results:
import ;
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date useTime;
{
"code": "200",
"message": "",
"result": [
{
"id": 93817601,
"useTime": "2025-04-18 15:06:18"
}
]
}
Then the question is,Why does @JSONField take effect, and @JsonFormat not take effect?
2. Cause analysis
By default, the JSON message converter used by Spring Boot is Jackson'sMappingJackson2HttpMessageConverter
, the core dependencies are:
<dependency>
<groupId></groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.11.3</version>
</dependency>
Now use Jackson's@JsonFormat
The annotation does not take effect, which means Spring Boot does not use the default one.MappingJackson2HttpMessageConverter
。
Using fastjson@JSONField
The annotation takes effect, indicating that Spring Boot uses the JSON message converter under fastjson, that is
FastJsonHttpMessageConverter
, dependencies are:
<dependency>
<groupId></groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
So how do you find where the code is configured?
The first step is to search globally in the projectFastJsonHttpMessageConverter
(Windows shortcut key: Ctrl+Shift+F), but it is likely that you can't search because
Projects in the company are generally inherited from the company's public xxx-spring-boot-starter.
Step 2: Press Shift key twice to searchFastJsonHttpMessageConverter
, and then look for a reference or subclass of the class (the subclass is most likely written in the company's underlying framework).
Then, it is very likely that you will find a code like the following:
@Configuration
public class FastJsonMessageConverterConfig {
@Bean
public HttpMessageConverters customConverters() {
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
return new HttpMessageConverters(new HttpMessageConverter[]{fastJsonHttpMessageConverter});
}
}
The above code explicitly registers oneFastJsonHttpMessageConverter
, and passHttpMessageConverters
Overrides the default HTTP message converter
(Jackson'sMappingJackson2HttpMessageConverter
), so Spring MVC will only handle JSON serialization/deserialization using fastjson.
This is also@JSONField
Take effect,@JsonFormat
The root cause of ineffectiveness.
3. Default behavior and global configuration
fastjson 1.2.36 and above, the date is serialized as a timestamp by default (such as 1744959978674). If you want to serialize the date to yyyy-MM-dd HH:mm:ss
(For example, 2025-04-18 15:06:18), it needs to be enabledWriteDateUseDateFormat
characteristic:
@Configuration
public class FastJsonMessageConverterConfig {
@Bean
public HttpMessageConverters customConverters() {
FastJsonConfig fastJsonConfig = new FastJsonConfig();
// Enable date formatting feature (disable timestamps)
();
// Set the date format (when not specified, the default is yyyy-MM-dd HH:mm:ss, but it is recommended to specify it clearly even if it is consistent with the default value)
("yyyy-MM-dd HH:mm:ss");
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
(fastJsonConfig);
return new HttpMessageConverters(new HttpMessageConverter[]{fastJsonHttpMessageConverter});
}
}
If a date field has special serialization requirements, you can use@JSONField
Flexible configuration of annotations (this annotation will override global configuration):
import ;
@JSONField(format = "yyyy-MM-dd")
private Date anotherUseTime;
Notes:
You need to be careful when modifying the global configuration. If an old project returns a time stamp when the original date type returns, and suddenly all of them are changed to return a string, it may cause the caller to report an error.
The article continues to be updated, welcome to follow the WeChat public account "Shencheng Strange People" to read it as soon as possible!