0

I am trying to create json object from LocaLDateTime but for some reason it is creating json like so, look for issueAt and expireAt key

json {"userID":0,"deviceID":0,"refreshToken":"93180548-23b3-4d1b-8b5b-a105b7cff7f9","issuedAt":{"year":2021,"monthValue":10,"dayOfMonth":27,"hour":9,"minute":22,"second":31,"nano":0,"month":"OCTOBER","dayOfWeek":"WEDNESDAY","dayOfYear":300,"chronology":{"id":"ISO","calendarType":"iso8601"}},"expiresAt":{"year":2021,"monthValue":10,"dayOfMonth":28,"hour":9,"minute":22,"second":31,"nano":0,"month":"OCTOBER","dayOfWeek":"THURSDAY","dayOfYear":301,"chronology":{"id":"ISO","calendarType":"iso8601"}}}

I want it to be like so

batch: [0,0,29a1bf70-648e-4cb5-aef8-5377cf702875,2021-10-26T12:36:10,2021-10-27T12:36:10] .

My code for creating the 2 dates is below

    String randomString = UUID.randomUUID().toString();
    Instant myInstant1 = Instant.now().truncatedTo(ChronoUnit.SECONDS);
    LocalDateTime issuedAt = LocalDateTime.ofInstant(myInstant1, ZoneId.systemDefault());
    System.out.println("issued_at : " + issuedAt);
    LocalDateTime expiresAt = issuedAt.plusDays(1);
    System.out.println("expires_at: " + expiresAt.plusDays(1));

In the below code is where I get the error when I try to use mapto to add the json object to my class object.

JsonObject json = new JsonObject()
                    .put("userID", userID)
                    .put("deviceID", deviceID)
                    .put("refreshToken", randomString)
                    .put("issuedAt", issuedAt)
                    .put("expiresAt", expiresAt);
                                    
                                
LOG.info("json {}", json.encode());

RefreshToken refreshTokenObj = json.mapTo(RefreshToken.class); //here I am trying to mapTo my class and I get the error
LOG.info("refreshTokenObj {}", refreshTokenObj);

The error I get is

2021-10-27 09:22:31.133+0330 [vert.x-eventloop-thread-1] ERROR com.galiy.main.MainVerticle - Unhandled: java.lang.IllegalArgumentException: Cannot construct instance of java.time.LocalDateTime (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator) at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: com.galiy.security.refreshToken.RefreshToken["issuedAt"]) at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:4236) ~[jackson-databind-2.11.4.jar:2.11.4]

and my RefreshToken model is like so,

public class RefreshToken {

private Integer id;
private Integer userID;
private Integer deviceID;
private String refreshToken;
private LocalDateTime issuedAt;
private LocalDateTime expiresAt;
ZAJ
  • 793
  • 3
  • 23
  • 50
  • Hi, it seems that you asked 2 questions and `JsonObject` is belong to `Gson` not in `Jackson`, did you mix the use of them? – LHCHIN Oct 27 '21 at 07:53
  • The error is due to the fact that `issuedAt` receives an object that cannot be parsed, as @LHCHIN observed are you using `Jackson` for deserialization ? – dariosicily Oct 27 '21 at 08:04
  • thanks for your comments. I am using the JsonObject in Vertx package `import io.vertx.core.json.JsonObject;` – ZAJ Oct 27 '21 at 08:18
  • You are welcome. If you are not using `jackson` for deserialization I cannot help, probably if the serialization as iso string is available can simplify your problem. – dariosicily Oct 27 '21 at 08:29
  • Hi, if you are using `Vert.x`, why `jackson-databind-2.11.4.jar:2.11.4` is shown in your error message? – LHCHIN Oct 27 '21 at 08:42
  • @LHCHIN because internally it uses Jackson-databind – ZAJ Oct 27 '21 at 08:46

2 Answers2

2

I am not familiar with Vert.x. But according to our discussion under the post, I simply add following 2 line of code before mapTo() and got no error.

ObjectMapper objectMapper = DatabindCodec.mapper();
objectMapper.registerModule(new JavaTimeModule());

Console output:

RefreshToken{id=null, userID=0, deviceID=0, refreshToken='9da220ce-bc66-4561-b924-988c7f394f2d', issuedAt=2021-10-27T17:21:28, expiresAt=2021-10-28T17:21:28}


And in my experience, you can also configure ObjectMapper to handle the output format of LocalDateTime as you want while serialization as follows:

objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
LHCHIN
  • 3,679
  • 2
  • 16
  • 34
  • Thanks for your comments. I managed to import everything from this code except DatabindCodec. where is this class from? – ZAJ Oct 27 '21 at 09:25
  • Once adding the dependency of `vertx-core`, you can use it by `import io.vertx.core.json.jackson.DatabindCodec;`. – LHCHIN Oct 27 '21 at 09:30
1

You will need to annotate your LocalDateTime member as follows:

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
LocalDateTime myTime

Here is the link to full answer that explains all the details: Spring Data JPA - ZonedDateTime format for json serialization

Michael Gantman
  • 7,315
  • 2
  • 19
  • 36
  • Thanks for your comment, but I am not using Spring. I am using vert.x – ZAJ Oct 27 '21 at 10:30
  • The question was asked in context of Spring. The solution is not dependant on Spring. It is related to JSON libraries and annotations. So the solution in that question (the first answer) is general and not Spring specific. So it will work for you just fine. – Michael Gantman Oct 27 '21 at 10:51