5 Replies Latest reply on May 24, 2019 9:42 AM by surfspider

    WildFly 15: Deserialize / serialize LocalDateTime as number

    g.hohl

      Hello everyone,

       

      in the following thread there is a discussion how to enable the behaviour, that JSON-B returns e.g. LocalDateTime as a timestamp in milliseconds:

      Resteasy exports dates in textual format on wildfly 14 (Java 11) as opposed to numeric format in wildfly 9 (Java 8)

      That works fine - with one downside: Before such values were returned as numbers, but now they are returned as strings.

       

      Is there any possibility to configure the JSON-B in a way that it returns such objects as numbers?

       

      My code:

      import javax.json.bind.Jsonb;
      import javax.json.bind.JsonbBuilder;
      import javax.json.bind.JsonbConfig;
      import javax.json.bind.annotation.JsonbDateFormat;
      import javax.ws.rs.Produces;
      import javax.ws.rs.core.MediaType;
      import javax.ws.rs.ext.ContextResolver;
      import javax.ws.rs.ext.Provider;
      
      import org.jboss.logging.Logger;
      
      @Provider
      @Produces(MediaType.APPLICATION_JSON)
      public class JsonbContextResolver implements ContextResolver {
      
      
          /** The logging. */
          private static Logger log = Logger.getLogger(JsonbContextResolver.class);
      
      
          private Jsonb         jsonB;
      
      
          public JsonbContextResolver() {
              super();
      
              this.initialize();
          }
      
      
          private void initialize() {
              JsonbConfig config;
      
      
              log.info("Created " + this.getClass().getSimpleName());
              config = new JsonbConfig();
              config.setProperty(JsonbConfig.DATE_FORMAT, JsonbDateFormat.TIME_IN_MILLIS);
              this.jsonB = JsonbBuilder.create(config);
          }
      
      
          @Override
          public Jsonb getContext(Class type) {
              log.info("Retrieved object class: " + type.toGenericString());
              return this.jsonB;
          }
      
      
      }
        • 1. Re: WildFly 15: Deserialize / serialize LocalDateTime as number
          g.hohl

          I went into the depths of JSON-B and Yasson. And I landed at the class org.eclipse.yasson.internal.serializer.LocalDateTimeTypeSerializer which is in charge of serialization and deserialization of LocalDateTime objects.  It inherits from org.eclipse.yasson.internal.serializer.AbstractDateTimeSerializer and returns a String. Using that org.glassfish.json.JSonGeneratorImpl#write(String) is called. And that method escapes the String with double quotes.

           

          Seems it is not an easy task which can't be done just be changing the configuration, doesn't it?

          • 2. Re: WildFly 15: Deserialize / serialize LocalDateTime as number
            g.hohl

            I found a solution here: http://json-b.net/users-guide.html

            I simply wrote a serializer which implements JsonbSerializer and JsonbDeserializer and added it to the JsonbConfig with "withSerializers" and "withDeserializers".

             

            Maybe one thing to add: The interfaces must be declared on the class of the object you pass to the JsonbConfig. I tried to implement an AbstractSerializer<T> implementing these 2 interfaces and it got confused because it couldn't handle the generics.

            • 3. Re: WildFly 15: Deserialize / serialize LocalDateTime as number
              surfspider

              I have the same problem as you.

              Unfortunately the above link does not work anymore. Do you have some example code or another link perhaps?

               

              I always get the following error in Wildfly 15.0.1 with yasson library.

               

              com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.LocalDate` (no Creators, like default construct, exist): no String-argument constructor&#x2F;factory method to deserialize from String value

               

              I use the following annotation for my date attribute in my entity:

               

              @JsonbDateFormat("dd-MM-yyyy")  

              private LocalDate mydate;

              • 4. Re: WildFly 15: Deserialize / serialize LocalDateTime as number
                surfspider

                I found the solution:

                 

                It seems to work if I replace the Eclipse Yasson libraries with the current Apache Johnzon implementation in my pom.xml.

                (see also: https://www.baeldung.com/java-json-binding-api)

                 

                <dependency>

                    <groupId>org.apache.geronimo.specs</groupId>

                    <artifactId>geronimo-json_1.1_spec</artifactId>

                    <version>1.2</version>

                </dependency>

                <dependency>

                    <groupId>org.apache.johnzon</groupId>

                    <artifactId>johnzon-jsonb</artifactId>

                    <version>1.1.11</version>

                </dependency>

                • 5. Re: WildFly 15: Deserialize / serialize LocalDateTime as number
                  surfspider

                  Now I get following error with GET requests:

                   

                  ERROR [org.eclipse.yasson.internal.Marshaller] - Invalid json.

                   

                  and the generated JSON is broken in the response.

                   

                  Unfortunately your link http://json-b.net/users-guide.html  does not work anymore. Maybe you have an alternative?