Hi I am seeking for some help,
previously I used to get my datetime field as 2022-06-30T22:39:22.235 0000
format but after adding one internal library(Org level) datetime fields are coming as 1656628762235
in json response.
I have tried to add @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
in my dto level but no luck also I tried adding below properties in yaml files.
spring.jackson.serialization.write-dates-as-timestamps: true
jackson-datatype-jsr310 version is : 2.9.10
jackson-databind : 2.9.10
spring-boot-2.1.11.RELEASE
please suggest what other option I can try to get the timestamp as in iso format.
@Setter
@Getter
public class TestRequestFormDto implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private UUID trfId;
private String testType;
private ItemDto item;
private List<RepItemsMappingDto> repItems;
private AdditionalQuestionsDto additionalQuestions;
private String hasRepItems;
private TestRequestInfoDto testRequestInfo;
private ItemInformationDto itemInformation;
private LabDto lab;
private Timestamp createdDate;
private String createdBy;
private String status;
private Timestamp modifiedDate;
private String modifiedBy;
private String pageLeftFrom;
private String referenceNumber;
private TrfVendorDto trfVendor;
private TrfFactoryDto trfFactory;
private String originCountry;
private String itemsVbu;
private String versionNumber;
}
previous date format:
{"createdDate": "2022-06-30T22:39:22.235 0000"}
current date format:
{"createdDate": 1656628762235}
CodePudding user response:
Use modern Time API
java.util.Date
and its subclasses are legacy.
Since Java 8 (which was released about 10 years ago) we have modern Time API which includes Instant
, LocalDateTime
and other classes from the java.time package
.
java.sql.Timestamp
as well as Date
is obsolete and discouraged to be used.
You're advised to use java.time.Instant
instead (if you have the ability to change the types in your DTO).
Seconds to Instant
The task would be simple if your timestamp were represented in seconds (unfortunately it's not, but for completeness I'll describe this option).
In this case, you would need to have a Bean of type JavaTimeModule
in the Spring Contexts. Spring-Boot will do the rest for you. JacksonAutoConfiguration
will grab the module and register it automatically.
@Configuration
public class JsonConfig {
@Bean
public JavaTimeModule javaTimeModule() {
return new JavaTimeModule();
}
}
Note: if the target field is of type Instant
no extra annotations required.
Milliseconds to Instant
In case if your timestamp represented in milliseconds and autoconfiguration would not work (you can try it, the parsed date would be very far in the future).
To resolve this problem, we need to configure ObjectMapper
manually by registering JavaTimeModule
module and instructing mapper about the precision of the timestamp. For that, would need to place two Beans Jackson2ObjectMapperBuilder
and ObjectMapper
in the Spring's Context.
@Configuration
public class JsonConfig {
@Bean
public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() {
return new Jackson2ObjectMapperBuilder();
}
@Bean
public ObjectMapper objectMapper() {
return jackson2ObjectMapperBuilder()
.build()
.registerModule(new JavaTimeModule())
.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false);
}
}
And as I've said before, no additional steps and no extra annotations on fields required (unless the property name doesn't match).
Usage example:
Input JSON:
{"timestamp": 1656628762235}
Output:
[2022,6,30,22,39,22,235000000]
If you can't a change the data type
As the last resort if you're forced to use legacy date-time representations, here's a couple of possible solutions:
You can declare all-args constructor in your POJO and annotate each argument with
@JsonProperty
. The trick is to declare the corresponding arguments of typelong
and parse milliseconds tojava.sql.Timestamp
manually. But judging by the number of field you have, this approach doesn't look like the best option.Another option would be to implement a custom
Deserializer
and annotate the fields of typeTimestamp
with@JsonDeserialize
annotation.