Home > Net >  java sql timestamp coming as milliseconds in rest api response
java sql timestamp coming as milliseconds in rest api response

Time:10-11

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 type long and parse milliseconds to java.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 type Timestamp with @JsonDeserialize annotation.

  • Related