Search code examples
scalajackson-databind

Marshall/Unmarshalling Scala Case class with Jackson Jsonformat not working


gradle configurations

            'com.fasterxml.jackson.core:jackson-databind:2.9.5',
            "com.fasterxml.jackson.module:jackson-module-scala_2.12:2.9.5",
            'com.fasterxml.jackson.datatype:jackson-datatype-joda:2.9.5',

case class looks like this

case class SampleCaseClass(@JsonProperty("a") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ") a: DateTime,
                                    @JsonProperty("b_id") b: String,
                                    @JsonProperty("c_id") c: String) {

}

instantiation

  val sampleCaseClass =
            SampleCaseClass(
                new DateTime(10L),
                "abc",
                "efg",
            )

converting case class to json

      val mapper = new ObjectMapper() with ScalaObjectMapper
      mapper.registerModule(DefaultScalaModule)
      mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
      mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
      val inputJson = new StringReader(mapper.writeValueAsString(sampleCaseClass))

Date value is coming

{"year":1970,"dayOfMonth":1,"dayOfWeek":4,"dayOfYear":1,"era":1,"millisOfDay":3600010,"weekOfWeekyear":1,"weekyear":1970,"monthOfYear":1,"yearOfEra":1970,"yearOfCentury":70,"centuryOfEra":19,"millisOfSecond":10,"secondOfMinute":0,"secondOfDay":3600,"minuteOfHour":0,"minuteOfDay":60,"hourOfDay":1,"chronology":{"zone":{"fixed":false,"uncachedZone":{"fixed":false,"cachable":true,"id":"Europe/Berlin"},"id":"Europe/Berlin"}},"zone":{"fixed":false,"uncachedZone":{"fixed":false,"cachable":true,"id":"Europe/Berlin"},"id":"Europe/Berlin"},"millis":10,"beforeNow":true,"afterNow":false,"equalNow":false}

JsonFormat for some reasons not working. where as JsonProperty works

how to make sure that date is properly formatted. I want to do this at case class level, because while converting json back to object I don't want to face any issues. Am trying to insert values into Elasticsearch. I am using springboot 2.7.6, internally it uses 7.17 Elasticsearch version. I am trying to use new JAVA API client to insert the values.


Solution

  • maybe the issue How to resolve case class Option[LocalDate] ? #332 could help to solve your problem. Looks like you need to register the JavaTimeModule for the ObjectMapper

    new ObjectMapper().registerModule(new JavaTimeModule).registerModule(DefaultScalaModule)
    

    also you need to add jackson-modules-java8 as dependency. This one has support for JSR-310 specification (Java 8 date/time types).

    If I'm not wrong, based on the dependencies you listed, you are using joda time. In thath case you would need to register the JodaModule for the ObjectMapper that comes from jackson-datatype-joda, the dependency that is already imported