2017-02-14 37 views
3

У меня есть класс Java используется в Spring загрузки приложения для десериализации объекта JSON, идущий от запроса с поля, как так:Java-шаблон даты для десериализации даты с переменным числом дробных секунд?

@JsonFormat(pattern="yyyy-MM-dd'T'HH:mm:ss[.SSS]XXX", timezone = "UTC") 
Instant timestamp; 

Она использует аннотацию Джексон V2.6.6 @JsonFormat десериализации " timestamp "в JSON, входящем в сеть.

Что я вижу в том, что, когда значение что-то вроде:

"2017-01-09T21:49:26.70Z"

нет никаких проблем.

Однако, если значение имеет единственное число дробных второго знака после запятой включены, или более трех, как:

"2017-01-09T21:49:26.7Z" or "2017-01-09T21:49:26.7000Z"

Тогда я получаю следующее сообщение об ошибке:

Caused by: java.time.format.DateTimeParseException: Text '2017-01-09T21:49:26.7Z' could not be parsed at index 19 
    at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949) ~[?:1.8.0_65] 
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1777) ~[?:1.8.0_65] 
    at com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer.deserialize(InstantDeserializer.java:150) ~[jackson-datatype-jsr310-2.6.6.jar:2.6.6] 
    at com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer.deserialize(InstantDeserializer.java:45) ~[jackson-datatype-jsr310-2.6.6.jar:2.6.6] 
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:520) ~[jackson-databind-2.6.6.jar:2.6.6] 
    at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:101) ~[jackson-databind-2.6.6.jar:2.6.6] 
    at com.fasterxml.jackson.module.afterburner.deser.SuperSonicBeanDeserializer.deserialize(SuperSonicBeanDeserializer.java:156) ~[jackson-module-afterburner-2.6.6.jar:2.6.6] 
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3736) ~[jackson-databind-2.6.6.jar:2.6.6] 
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2764) ~[jackson-databind-2.6.6.jar:2.6.6] 

Что могу ли я сделать, чтобы исправить этот шаблон, чтобы он мог быть гибким с точки зрения количества дробных вторых десятичных знаков, которые он принимает? Я понимаю, что в форматировании дат Java есть понятие мягкости: https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html

Но я не уверен, как настроить отображение объекта в режим снисхождения.

+0

Если ничего не работает, вы можете прочитать его как 'String' и проанализировать его, используя регулярное выражение, возможно, – Caner

ответ

0

Update вашей реализация Java

Просто догадка ...

Я подозреваю, что вы можете поразить некоторые java.time ошибки в предыдущих версиях Java 8. Было несколько разбора связанные с ошибками, некоторые фиксированными позже обновления Java 8 и некоторые исправленные в Java 9.

Я предполагаю, что строка 1.8.0_65 в тексте ошибки относится к Java 8 Update 65. В настоящее время Oracle implementation is at Update 121.

Что такое форматирование?

Я не знаю Jackson. Интересно, какие именно DateTimeFormatter они вызывают. Я не вижу эту информацию в вашей цитате с ошибкой.

Можете ли вы опустить определение шаблона и посмотреть, какое поведение по умолчанию для Джексона?

Нет проблем с Instant.parse

Я не вижу такой проблемы при анализе ваших строк, вызвав Instant.parse в Java 8 Update 121 на MacBook Pro (Retina, 15 дюймов, конец 2013 г.) с 16 гигабайтами RAM работает MacOS Sierra 10.12.3 с NetBeans 8.2.

System.out.println ("Java vendor: " + System.getProperty ("java.vendor")); 
System.out.println ("Java version: " + System.getProperty ("java.version")); 

List<String> strings = new ArrayList<>(); 
strings.add ("2017-01-09T21:49:26.7Z"); 
strings.add ("2017-01-09T21:49:26.70Z"); 
strings.add ("2017-01-09T21:49:26.700Z"); 
strings.add ("2017-01-09T21:49:26.7000Z"); 
strings.add ("2017-01-09T21:49:26.70000Z"); 

for (String string : strings) { 
    try { 
     Instant instant = Instant.parse (string); 
     System.out.println ("GOOD - string: " + string + " parsed: " + instant); 
    } catch (DateTimeParseException e) { 
     System.out.println ("ERROR - Failed to parse string: " + string); 
    } 
} 
System.out.println ("Done."); 

При запуске.

Java vendor: Oracle Corporation 
Java version: 1.8.0_121 
GOOD - string: 2017-01-09T21:49:26.7Z parsed: 2017-01-09T21:49:26.700Z 
GOOD - string: 2017-01-09T21:49:26.70Z parsed: 2017-01-09T21:49:26.700Z 
GOOD - string: 2017-01-09T21:49:26.700Z parsed: 2017-01-09T21:49:26.700Z 
GOOD - string: 2017-01-09T21:49:26.7000Z parsed: 2017-01-09T21:49:26.700Z 
GOOD - string: 2017-01-09T21:49:26.70000Z parsed: 2017-01-09T21:49:26.700Z 

Вы также можете увидеть эту же code run live at IdeOne.com без проблем, работает Java 8 Update 121 реализации Oracle.

Проблемы с DateTimeFormatter.ofPattern

Я попробовал ваш шаблон форматирования, а также. Он работает для .70 и .700, но не для других.

DateTimeFormatter f = DateTimeFormatter.ofPattern ("yyyy-MM-dd'T'HH:mm:ss[.SSS]XXX" , Locale.US); 
for (String string : strings) { 
    try { 
     OffsetDateTime odt = OffsetDateTime.parse (string , f); 
     System.out.println ("GOOD - string: " + string + " parsed: " + odt); 
    } catch (DateTimeParseException e) { 
     System.out.println ("ERROR - Failed to parse string: " + string); 
    } 
} 
System.out.println ("Done with 'DateTimeFormatter.ofPattern'."); 
ERROR - Failed to parse string: 2017-01-09T21:49:26.7Z 
GOOD - string: 2017-01-09T21:49:26.70Z parsed: 2017-01-09T21:49:26.700Z 
GOOD - string: 2017-01-09T21:49:26.700Z parsed: 2017-01-09T21:49:26.700Z 
ERROR - Failed to parse string: 2017-01-09T21:49:26.7000Z 
ERROR - Failed to parse string: 2017-01-09T21:49:26.70000Z 

ISO 8601

FYI, формат строк, таких как 2017-01-09T21:49:26.70Z определено в стандарте ISO 8601. Классы java.time используют эти стандартные ISO 8601 форматы по умолчанию при разборе или генерации строк, представляющих значения даты и времени.

Этот конкретный формат использует T для разделения части года-месяца с части часа-минуты-секунды. Z подходит для Zulu и означает UTC.

Вы можете увидеть гораздо больше информации по searching StackOverflow.

+0

Просто обновлено до 1.8.0.121, и оно по-прежнему не работает на« 2017-01-09T21: 49: 26.7Z »с использованием шаблона: "yyyy-MM-dd'T'HH: mm: ss [.SSS] XXX" –

+1

@AdamBronfin Избавьтесь от '@ JsonFormat' в целом. Если вы это сделаете, Джексон будет использовать 'DateTimeFormatter.ISO_INSTANT', что и использует' Instant # parse', что здесь предлагает Basil. –

+0

@SotiriosDelimanolis Я согласен с вашим предложением в качестве эксперимента. Но я добавил еще код, показывающий, что его шаблон форматирования должен работать так же, как 'DateTimeFormatter.ISO_INSTANT'. –

 Смежные вопросы

  • Нет связанных вопросов^_^