0

I want to implement a custom validator in a Spring Boot v1.5.14.RELEASE app. First I create a custom constraint annotation:

I have this object:

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
@SuperBuilder
public class Hotel {

    @JsonFormat(pattern = "yyyy-MM-dd")
    private OffsetDateTime interactionDurationStart;
    @JsonFormat(pattern = "yyyy-MM-dd")
    private OffsetDateTime interactionDurationEnd;

}

in the yml:

spring:
  jackson:
    mapper:
      DEFAULT_VIEW_INCLUSION: true
    serialization:
      WRITE_DATES_AS_TIMESTAMPS: false

and in my configuration file:

@Primary
@Bean
public ObjectMapper objectMapper() {

    ObjectMapper objectMapper = new ObjectMapper();
    //objectMapper.registerModule(new JavaTimeModule());
    SimpleModule simpleModule = new SimpleModule();
    simpleModule.addSerializer(OffsetDateTime.class, new JsonSerializer<OffsetDateTime>() {
        @Override
        public void serialize(OffsetDateTime offsetDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
            jsonGenerator.writeString(DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(offsetDateTime));
        }
    });
    objectMapper.registerModule(simpleModule);

    return objectMapper;
}

but this is what i see in the API response

"interactionDurationEnd" : {
      "offset" : {
        "totalSeconds" : 7200,
        "id" : "+02:00",
        "rules" : {
          "transitionRules" : [ ],
          "transitions" : [ ],
          "fixedOffset" : true
        }
      },
Sandro Rey
  • 2,429
  • 13
  • 36
  • 80

3 Answers3

5

Spring MVC uses Jackson as default json object mapper. Jackson doesn't support serialization/deserialization for java8's Time API by default, but it provides a module for integrating it. Just include this dependency in your pom.xml:

<dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
  </dependency>

Spring Boot auto-configuration will detect the Jackson module class JavaTimeModule and will added it to the ObjectMapper instance.

If you're creating the ObjectMapper instance by hand, you can add the module using this line:

objectMapper.registerModule(new JavaTimeModule());
eHayik
  • 2,981
  • 1
  • 21
  • 33
  • 2
    It’s not my home field, but I was under the impression that jackson-datatype-jsr310 was merged into [jackson-modules-java8](https://github.com/FasterXML/jackson-modules-java8), and that you should nowadays prefer to use the latter. – Ole V.V. Aug 08 '19 at 22:02
0

That happens because the ObjectMapper that spring uses recognize only Date by default. Have a look at this Jackson date-format for OffsetDateTime in Spring Boot if you want to use OffsetDateTime field as you will need to register a serializer / deserialize to do the job for you.

If you want to change the field type to Date then I am not sure if JsonFormat will work as I have never used it. My solution to the case is providing an ObjectMapper bean to spring with objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")) which does the trick.

Hope that helped!

Michael Michailidis
  • 1,002
  • 1
  • 8
  • 21
0

what version of jackson-databind ?

try adding the Shape

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-mm-dd")

if it work then that your problem there was a bug with old version jackson-bind that required shape to be use or by default it will be any.

DarkVision
  • 1,373
  • 3
  • 20
  • 33