1

I have implemented a Formatter in a REST Spring Boot web service application to format all LocalDateTime (Java 8) attributes so that they get displayed in a specific format in the web service response.

public class LocalDateTimeFormatter implements Formatter<LocalDateTime> {

    @Override
    public String print(LocalDateTime temporal, Locale locale) {
        DateTimeFormatter formatter = DateTimeFormatter
                .ofPattern("yyyy-MM-dd HH:mm:ss");
        return formatter.format(temporal);
    }

    @Override
    public LocalDateTime parse(String text, Locale locale)
            throws ParseException {
        return LocalDateTime.parse(text);
    }

}

The formatter has also been registered as shown below so that it works at the application level in order to avoid annotating all LocalDateTime attributes individually

@Configuration
public class ContentFormatter implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
            registry.addFormatter(new LocalDateTimeFormatter());
    }
}

But no formatting is applied to the response from the web service, accessDate being the LocalDateTime type of attribute

{
  "content" : "Hello, World!",
  "id" : 0,
  "accessDate" : "2020-04-07T19:56:41.48"
 }
Seema Garg
  • 153
  • 1
  • 9

2 Answers2

0

You probably don't even need to implement your formatted and register it. Just annotate your LocalDateTime property as follows:

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
public LocalDateTime getTime() {
    return time;
}

Also, you might need to add the following dependency:

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

See this question and its answer for details: Spring Data JPA - ZonedDateTime format for json serialization

Michael Gantman
  • 7,315
  • 2
  • 19
  • 36
  • 1
    Thank you Michael for your answer, it definitely works. But I need the solution to work at entire application level in order 1) To avoid annotating all LocalDateTime attributes getters individually 2) To have the implementation that works for all response formats (json/xml) – Seema Garg Apr 07 '20 at 15:09
0

You can use StdSerializer

public class JacksonLocalDateSerializer extends StdSerializer<LocalDate> {

  private static final long serialVersionUID = -7880057299936771237L;

  private static final DateTimeFormatter formatter =
      DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
      .withResolverStyle(ResolverStyle.STRICT);

  public JacksonLocalDateSerializer() {
    this(null);
  }

  public JacksonLocalDateSerializer(Class<LocalDate> type) {
    super(type);
  }

  @Override
  public void serialize(LocalDate value, JsonGenerator jsonGenerator,
      SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
    jsonGenerator.writeString(formatter.format(value));
  }
}

Then add configuration for the serializer for applicable the entire application


@Configuration
public class JacksonConfig {

  @Bean
  @Primary
  public ObjectMapper configureObjectMapper() {

    JavaTimeModule javaTimeModule = new JavaTimeModule();

    javaTimeModule.addSerializer(LocalDateTime.class, new JacksonLocalDateTimeSerializer());
    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(javaTimeModule);
    return mapper;
  }

}
Eklavya
  • 17,618
  • 4
  • 28
  • 57
  • Thanks Abinash for your response. I am still looking for some solution which is slightly more compact and works for all formats (xml, json) for entire application and specifically Formatter interface. I see few implementations similar to mine on Github, but in my case this is not working – Seema Garg Apr 11 '20 at 11:47