#java #json #jackson
#java #json #джексон
Вопрос:
Я внедряю приложение в Spring Boot. Использование Джексона.
Можно ли в любом случае указать JsonFormat для анализа двух типов даты, например:
2020-10-06T10:15:30 01:00
2020-10-06T10:15:30
Мое текущее поле:
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss Z")
private OffsetDateTime interval;
Должен ли я где-то указывать какой-то ObjectMapper в конфигурации?
Я извлекаю эту ошибку:
com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.time.OffsetDateTime` from String "2020-10-06T10:15:30 01:00": Failed to deserialize java.time.OffsetDateTime: (java.time.format.DateTimeParseException) Text '2020-10-06T10:15:30 01:00' could not be parsed at index 10
С уважением
Комментарии:
1. В вашем шаблоне отсутствует разница
T
между датой и временем… Сделайте это"yyyy-MM-dd'T'HH:mm:ssZ"
и повторите попытку. Вjava.time
шаблоне даже должно быть"uuuu-MM-dd'T'HH:mm:ssxxx"
, но я не знаю, сможет ли JPA справиться с этим.2. Он работает для 2020-10-06T10:15:30 01:00, но не для 2020-10-06T10:15:30
3. В последнем вводе отсутствует смещение
01:00
, вы можете попытаться сделать его необязательным в pattern ("yyyy-MM-dd'T'HH:mm:ss[Z]"
) , но я не думаю, что результат всегда будет действительнымOffsetDateTime
. Если вы обрабатываетеString
s таких разных форматов (важные элементы могут быть там или нет), вам придется использовать разные шаблоны. Вы не можете создатьOffsetDateTime
синтаксический анализ aString
, который не имеет / указывает смещение.4. @Ernesto Какое смещение должно
interval
иметь значение, если во входной строке не указано смещение часового пояса?
Ответ №1:
Вам нужно проанализировать, используя a DateTimeFormatter
с дополнительным смещением зоны, поэтому вам нужен пользовательский JsonDeserializer
:
public class OffsetDateTimeOptionalZoneDeserializer extends StdScalarDeserializer<OffsetDateTime> {
private static final DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.optionalStart()
.appendOffsetId()
.optionalEnd()
.parseDefaulting(ChronoField.OFFSET_SECONDS, 0)
.toFormatter();
public OffsetDateTimeOptionalZoneDeserializer() { super(OffsetDateTime.class); }
@Override
public OffsetDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
return OffsetDateTime.parse(p.getText(), formatter);
}
}
Тест
public class Test {
@JsonDeserialize(using = OffsetDateTimeOptionalZoneDeserializer.class)
private OffsetDateTime interval;
public static void main(String[] args) throws Exception {
String json = "["
"{ "interval": "2020-10-06T10:15:30 01:00" },"
"{ "interval": "2020-10-06T10:15:30Z" },"
"{ "interval": "2020-10-06T10:15:30" }"
"]";
ObjectMapper mapper = new ObjectMapper();
Test[] tests = mapper.readValue(json, Test[].class);
for (Test t : tests)
System.out.println(t.interval);
}
}
Вывод
2020-10-06T10:15:30 01:00
2020-10-06T10:15:30Z
2020-10-06T10:15:30Z