java Kafka client doesn't serialize LocalDateTime to JSR-310 and ignores annotations and custom serializer

184 Views Asked by At

I need to send to kafka json serialized from the following pojo:

  @Builder
  @Data
  @NoArgsConstructor
  @AllArgsConstructor
  public class MyObject {
    @NonNull
    @JsonProperty(required = true)
    @JsonSerialize(using = LocalDateTimeSerializer.class)
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    LocalDateTime eventTime;
}

Unfortunatelly even with annotation I see that in a result json I get the following data instead of formatted string:

{
    "eventTime": [
        2023,
        1,
        30,
        8,
        57,
        57,
        248107000
    ]
}

According to other answers with similar problem I tried few things: I created custom serializer:

public class JRS310Serializer extends JsonSerializer<MyObject> {
    public JRS310Serializer() {
        super();
        objectMapper.registerModule(new JavaTimeModule());
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
    }
}

I added it to application.yaml:

spring:
  kafka:
    producer:
      value-serializer: org.package.JRS310Serializer 

And I also added this to application.yaml:

spring:
  jackson:
    serialization:
      WRITE_DATES_AS_TIMESTAMPS: false

But nothing helps. During debugging I saw that objectMapper inside of my custom serializer created properly. I even can get normal json if I call instance of objectMapper provided by serializer to KafkaProducer using the following command:

objectMapper.writeValueAsString(MyObject.builder().eventTime(LocalDateTime.now()).build());

But the problem is that for serializing JSON kafka uses ObjectWriter class instance (not ObjectMapper) with the following command

this.writer.writeValueAsBytes(MyObject.builder().eventTime(LocalDateTime.now()).build())

and it is always returns the wrong value with arrays. First I tried it in 2.7.7 Spring boot with managed dependencies. Then updated to 2.7.8 but it didn't help. Is it a new bug or I do something wrong? Thank in advance.

1

There are 1 best solutions below

0
Gekster On

helped overriding of public byte[] serialize(String topic, @Nullable T data) JsonSerializer method where instead of ObjectWriter I use ObjectMapper:

public class JRS310Serializer extends JsonSerializer<MyObject> {
    public JRS310Serializer() {
        super();
        objectMapper.registerModule(new JavaTimeModule());
        objectMapper.configure( SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
    }

    @Nullable
    @Override
    public byte[] serialize(String topic, @Nullable MyObject data) {
        if (data == null) {
            return null;
        } else {
            try {
                return objectMapper.writeValueAsBytes(data);
            } catch (IOException var4) {
                throw new SerializationException("Can't serialize data [" + data + "] for topic [" + topic + "]", var4);
            }
        }
    }
}