vince
vince

Reputation: 45

LocalDateTime not displaying as timestamps (ie as a long) java 8 spring boot 2.2.0

After visiting all pages about it where I found and tried many many ideas, none worked for me so I write this post. My API in java 8 spring boot 2.2.0 have beans that are generated from xsd files. I recently changes the Date type to LocalDateTime (because deprecation so it's time to change). The problem is, before, Date were display in a timestamp format (as a long) and now LocalDateTime are display in an array and I don't want it.

What I tried to solve:

Here is a snippet of the configuration class for message converters :

@Configuration
   public class MVCConfigure implements WebMvcConfigurer {
    @Autowired
    private ObjectMapper jacksonObjectMapper;

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {

        converters.removeIf(c -> c instanceof MappingJackson2HttpMessageConverter);

        jacksonObjectMapper.enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        converters.add(httpMessageConverterV1V2);

Nothing of theses solutions worked and I still get an array for my LocalDateTime (and I want a long).

Here is how I get the LocalDateTime :

private LocalDateTime getFirstLocalDateTime(final SolrDocument doc, final String key) {
        LocalDateTime ldt = null;
        Date solrDate = (Date) doc.getFirstValue(key);
        if(solrDate != null){
            ldt = solrDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        }
        return ldt;
    }

ps : The reason I use Date to get the Date from SolrDoc is because I can't cast to LocalDateTime directly

actual value : "lastIndexedDate": [ 2022, 1, 4, 2, 2, 2, 655000000 ]

desire value : "lastIndexedDate": 1641261722655

So, it is possible to get what I want ?

Upvotes: 0

Views: 1584

Answers (2)

Maxxxx
Maxxxx

Reputation: 159

I'd rather set this config so you don't have to create a custom serializer:

spring:
    jackson:
        serialization:
          write-dates-as-timestamps: true

That or set it in your mapper:

   @Bean
    public MappingJackson2HttpMessageConverter jsonConverter() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new JavaTimeModule());
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true);
        mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
        mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, true);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);
        return new MappingJackson2HttpMessageConverter(mapper);
    }

Upvotes: 0

vince
vince

Reputation: 45

Thanks to @deHaar who gave me some hints I've found how to proceed.

I created a custom serializer :

public class LocalDateTimeSerialize extends StdSerializer<LocalDateTime> {

    public LocalDateTimeSerialize(Class<LocalDateTime> t) {
        super(t);
    }

    @Override
    public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        Long l = localDateTime.toInstant(OffsetDateTime.now().getOffset())
                .toEpochMilli();
        jsonGenerator.writeString(l.toString());
    }
}

I change my extendMessageConverters to use this custom serializer in my objectMapper :

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule()
                .addSerializer(LocalDateTime.class, new LocalDateTimeSerialize(LocalDateTime.class)));

Upvotes: 1

Related Questions