Фронтенд отправляет даты в формате: 2024-06-01T05:55:04 от datetime-local control.
Пример контроллера REST:
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class ExampleResource {
@POST
public RestResponse<Example> create(Example example) {
return RestResponse.ok(exampleService.create(example));
}
}
@Data
public class Example {
@JsonProperty("creationTime")
private OffsetDateTime creationTime; // from front-end comes 2024-06-01T05:55:04
}
Здесь добавлен собственный десериализатор для OffsetDateTime:
@Singleton
public class ObjectMapperConfig implements ObjectMapperCustomizer {
public void customize(ObjectMapper mapper) {
var module = new SimpleModule();
module.addDeserializer(OffsetDateTime.class, new CustomOffsetDateTimeDeserializer());
mapper.registerModule(module);
}
static class CustomOffsetDateTimeDeserializer extends JsonDeserializer<OffsetDateTime> {
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
// figured out that this method is not called during deserialization
@Override
public OffsetDateTime deserialize(JsonParser p, DeserializationContext ctx) throws IOException {
String dateString = p.getText();
try {
return OffsetDateTime.parse(dateString);
} catch (Exception e) {
var localDateTime = LocalDateTime.parse(dateString, FORMATTER);
return localDateTime.atOffset(ZoneOffset.systemDefault().getRules().getOffset(localDateTime));
}
}
}
}
Я попробовал другой подход - переопределить bean-компонент ObjectMapper по умолчанию:
@Produces
@Singleton
public ObjectMapper objectMapper() {
var module = new SimpleModule();
module.addDeserializer(OffsetDateTime.class, new CustomOffsetDateTimeDeserializer());
var objectMapper = new ObjectMapper();
objectMapper.registerModule(module);
return objectMapper;
}
Ничего из вышеперечисленного не работает, и Quarkus не может десериализовать даты. Браузер получает ответ HTTP 400 Bad Request без тела.
Я запустил отладчик и понял, что InstantDeserializer по умолчанию используется для десериализации OffsetDateTime.
Как правильно настроить собственный десериализатор для OffsetDateTime?
Должен ли я использовать другой подход для анализа дат, например от 2024-06-01T05:55:04 до OffsetDateTime?




Наконец-то создал миксин, и он работает.
@Singleton
public class ObjectMapperConfig implements ObjectMapperCustomizer {
public void customize(ObjectMapper mapper) {
mapper.addMixIn(OffsetDateTime.class, DateMixin.class); // add mixin
}
// This mixin will be used to deserialize OffsetDateTime
@JsonDeserialize(converter = CustomOffsetDateTimeConverter.class)
static class DateMixin {
}
// Define a converter from String to OffsetDateTime
static class CustomOffsetDateTimeConverter extends StdConverter<String, OffsetDateTime> {
// We will try to parse this format on error
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
@Override
public OffsetDateTime convert(String dateString) {
try {
// First try to parse as OffsetDateTime
return OffsetDateTime.parse(dateString);
} catch (Exception e) {
// Then continue to parse using our format (without offset)
var localDateTime = LocalDateTime.parse(dateString, FORMATTER);
// Now use system default timezone to convert local datetime to offset datetime
return localDateTime.atOffset(ZoneOffset.systemDefault().getRules().getOffset(localDateTime));
}
}
}
}