Deserialize Long(Epoch Time) to Java Date Object using GSON - gson

I am subscribing to an SQS and the message body has a few epoch times. It looks like below
"createdAt" : 1660744139,\n "updatedAt" : 1660744139,\n
I have a Java POJO which contains 2 fields
Date createdAt;
Date updatedAt;
I am using GSON to deserialize the SQS message body to my POJO, but it's failing with an error com.google.gson.JsonSyntaxException: 1660744139.
My JSON instantiation looks like
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
If I understand it right, the error is being thrown because I am trying to deserialize a Long type to Date. What will be the correct way to deserialize?
I have seen suggestions to instantiate my GSON object with dateFormatter, but not sure if that will work for my case. Thank you.

Related

POJO to Entity mapping with ModelMapper

My POJO has a variable annotated like this
#JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSxxx")
#JsonDeserialize(using = ZonedDateTimeDeserializer.class)
private ZonedDateTime startTs;
//other private variables
My goal is to map this to an Entity for which I'm using ModelMapper and the sample code goes like this
public POJOEntity mapToPOJOEntity(POJO pojo) {
return modelMapper.map(pojo, POJOEntity.class);
}
After mapping when I look at the startTs variable in debug mode it has the desired format but when I check in the db startTs is saving as a whole ZonedDateTime object rather than the desired format I specified in POJO. Did anyone face this issue if yes can someone please help?
Value saved in cosmosDB:
Expected output: "startTs": "2023-01-12T08:58:32.452-06:00"
PS: CosmosDB, spring-boot, Java8, ModelMapper version: 2.3.8

Converting java.sql.timestamp to millisecond format

I have a private java.sql.Timestamp myDate in some model (POJO) class like below
private String isActive;
private Date dob;
private Timestamp createdDate;
private Timestamp lastMktPrefUpdateAt;
We were using spring boot version to 1.5.10.RELEASE and REST API response for timestamp field was in millisecond format like below -
{
"isActive": "y",
"lastMktPrefUpdateAt": 1632195609787,
"dob": "08/12/1991",
"createdDate": 1632195609788
}
We have recently upgraded the spring boot version to 2.3.0.RELEASE and this started sending timestamp field in response to some ISO format like below -
{
"isActive": "y",
"lastMktPrefUpdateAt": "2021-09-20T22:10:09.787+0000",
"dob": "07/12/1991",
"createdDate": "2021-09-20T22:10:09.788+0000"
}
Can someone please help answering, how can we format Timestamp back to millisecond format?
We need to format Timestamp at global level meaning without changing all the POJO classes.
Try this in your properties file
spring.jackson.serialization.write-dates-as-timestamps:true
OR
Use #JsonFormat(shape = JsonFormat.Shape.NUMBER) above the property that you want.
Update
If you want to add millis to your timestamp, try to pass the long value to the Timestamp constructor and call the getTime() method to receive a 13-digits timestamp.
long now = System.currentTimeMillis();
Timestamp timeStamp= new Timestamp(now);
System.out.println(timeStamp.getTime());
You could convert that string to a ZonedDateTime object which has a .toInstant().toEpochMilli() method.
Something like:
long millis = ZonedDateTime.of(LocalDateTime.parse(str), ZoneId.of("Etc/UTC")).toInstant().toEpochMilli();
see:
How to get milliseconds from LocalDateTime in Java 8
https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html
https://docs.oracle.com/javase/8/docs/api/java/time/ZonedDateTime.html
However, I would recommend refactoring the system to use the immutable LocalDatTime object at a later point.
(There may be an appropriate annotation you can put on that timestamp field to parse it in a specific way, but not one that I am aware of.)

Spring Boot Open Api Request LocalTime

I use Spring Boot 2.4.5, springdoc-openapi-ui 1.5.7,
My Entity has fields:
private LocalDate beginDate;
private LocalTime beginTime;
Request body
This option does not work
{
"beginDate": "2021-04-25",
"beginTime": {
"hour": 0,
"minute": 0,
"second": 0,
"nano": 0
}
And this worker
{
"beginDate": "2021-04-25",
"beginTime": "00:00:00"
}
I tried various field annotations and adding dependencies, but I got a 400 or 500 error.
I see two possible solutions:
configure the schema display in Swagger " 00:00:00"
properly process the json with the painted components
Thank you in advance for your help!
Thats because you need to define a deserializer so, that your request can be properly handled when passing 4 fields (hour/min/sec/nano) instead of just a single String field.
#JsonDeserialize(using = LocalTimeDeserializer.class)
private LocalTime beginTime;
you may also want to consider using this feature on your ObjectMapper when writing your deserialization class.
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());

How to pass a value of type Date in a Spring Boot Rest Call?

I have a class Model Object class as #RequestBody to a RestController in Spring Boot
#Data
class User {
private String name;
private Date dob;
}
I am calling this API from postman with the following JSON body
{
"name" : "Michael",
"dob" : "13/09/19"
}
I get a status 200 OK with this message
'Error occurred while parsing body. Please try with the correct payload.'
My data is not getting submitted. I know the problem is with date, how do I send the proper date?
You could try to annotate the dob field like this:
#JsonFormat(pattern="dd/MM/yy")
private Date dob;
Source: https://www.baeldung.com/spring-boot-formatting-json-dates

Unable to deserialize a field when using FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES

I am using gson for deserialization. I have a field with the name "listName" it has #Expose annotation.
When I set FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES in GsonBuilder and create Gson object using this GsonBuilder, then that field is not getting deserialized.
When I do not use FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES then that field is getting serialized.
Why is this happening?
The json field name should be "list_name" and your pojo object would have the field listName, when you are using that FieldNamingPolicy.
JSON:
{
"list_name": ""
}
POJO CLASS:
class POJO
{
String listName;
}
IF, when you do not use FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES and that field IS getting deserialized [sic]... then my guess is that your json field name is also "listName".

Resources