2015-02-26 5 views
9

Я пишу приложение Java 8 Spring MVC, которое обменивается данными с устаревшим приложением «Прогресс OpenEdge», используя службу REST (для этого я использую RestTemplate от Spring). Данные, которые мне нужно прочитать и записать в приложение «Прогресс», содержат некоторые даты. В приложении Java я использую тип данных java.time.LocalDate для представления этих полей, и я использую Jackson для сериализации/десериализации данных в/из Json.Сериализовать java.time.localdate в json, используя Jackson

Проблема, которую я испытываю, заключается в следующем. Когда я отправляю данные из приложения «Прогресс», дата отправляется как «2015-01-02» и хранится в моей Java-сущности как LocalDate, как и ожидалось. Когда данные отправляются на веб-интерфейс, Json также содержит дату в том же формате. Когда я изменяю информацию в веб-интерфейсе и применяю ее, она также отправляется обратно в приложение Java как «2015-01-02» и снова сохраняется как LocalDate без проблем. Но когда я отправляю данные в приложение «Прогресс», получаемый Json I не содержит дату «2015-01-02», а как массив, содержащий три поля (2015.0, 1.0, 2.0) и приложение «Прогресс» не удалось вернуть это значение в поле даты в базе данных.

Offcourse Я могу написать преобразование на стороне Прогресс, чтобы преобразовать массив обратно в дату, но я хотел бы избежать этого, поскольку я ожидаю, что дата всегда будет отправляться в формате ISO 8601.

В соответствии с информацией, которую я нахожу в Jackson, java.time.LocalDate представлен как массив, когда включен WRITE_DATES_AS_TIMESTAMPS, но у меня это отключено (а когда дата отправляется на веб-интерфейс, это не время отправки как массив ...)

Вот некоторые соответствующий код:

CustomObjectMapper:

@Service 
public class CustomObjectMapper extends ObjectMapper 
{ 
    public CustomObjectMapper() 
    { 
    this.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, 
        false); 
    } 
} 

конфигурация в моей servlet.xml

<mvc:annotation-driven> 
    <mvc:message-converters> 
    <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> 
     <property name="objectMapper" ref="customObjectMapper"/> 
    </bean> 
    </mvc:message-converters> 
</mvc:annotation-driven> 

<bean id="customObjectMapper" class="com.msoft.utility.CustomObjectMapper"/> 

Определение поля:

@JsonDeserialize(using = LocalDateDeserializer.class) 
@JsonSerialize(using = LocalDateSerializer.class) 
private LocalDate deliveryDate; 

Я использую Java 8 с Spring 4.1.5 и 2.5.1 Джексона.

Любые советы, как я могу получить эту работу или должны были искать решение было бы весьма признателен, как я уже работал над этим в течение почти 2 дней ...

Благодаря

EDIT :

Некоторой дополнительная информация ...

Я включил модуль Джексон JSR-310 в моем pom.xml. Вот releveant часть моего файла ... п

<dependency> 
    <groupId>com.fasterxml.jackson.core</groupId> 
    <artifactId>jackson-core</artifactId> 
    <version>2.5.1</version> 
</dependency> 
<dependency> 
    <groupId>com.fasterxml.jackson.core</groupId> 
    <artifactId>jackson-annotations</artifactId> 
    <version>2.5.1</version> 
</dependency> 
<dependency> 
    <groupId>com.fasterxml.jackson.core</groupId> 
    <artifactId>jackson-databind</artifactId> 
    <version>2.5.1</version> 
</dependency> 
<dependency> 
    <groupId>com.fasterxml.jackson.datatype</groupId> 
    <artifactId>jackson-datatype-jsr310</artifactId> 
    <version>2.5.1</version> 
</dependency> 
<dependency> 
    <groupId>org.springframework</groupId> 
    <artifactId>spring-test</artifactId> 
    <version>4.1.5.RELEASE</version> 
    <scope>test</scope> 
    <type>jar</type> 
</dependency> 
<dependency> 
    <groupId>org.springframework</groupId> 
    <artifactId>spring-webmvc</artifactId> 
    <version>4.1.5.RELEASE</version> 
</dependency> 
<dependency> 
    <groupId>org.springframework.data</groupId> 
    <artifactId>spring-data-jpa</artifactId> 
    <version>1.7.2.RELEASE</version> 
</dependency> 

Кроме того, если я правильно понял, то весна будет зарегистрировать этот модуль автоматически, когда он обнаружен. Смотрите информацию о Jackson2ObjectMapperFactoryBean

Обратите внимание, что Джексон JSR-310 и модули поддержки Joda-Time будут зарегистрированы автоматически при наличии (а когда Java 8 и Joda время сами доступны, соответственно).

Так что я не думаю, что я должен сделать что-нибудь еще, чтобы получить эту работу правильно, но очевидно, что я до сих пор не хватает что-то ...

+0

Для чего это стоит, вы не должны использовать аннотации, если модуль правильно зарегистрирован. Обозначения аннотации будут использоваться, а зарегистрированные обработчики по умолчанию не вызываются. Это может быть или не иметь значения, поскольку инициализация немного отличается. – StaxMan

+0

Если я удалю аннотации в свойстве deliveryDate, дата отправляется с Java как объект со следующей структурой: {«год»: 2015, «месяц»: «ЯНВАРЬ», «dayOfMonth»: 2, «dayOfWeek»: "пятница", "эра": "С", "DayOfYear": 2, "leapYear" ложь "monthValue": 1, "хронология": { "идентификатор": "ISO", "calendarType": "ISO8601" }} вместо 2015/01/02, я бы хотел. Спасибо за помощь, но все же не то, что я ищу ... – HeinoVDS

+0

та же проблема ... вы нашли решение –

ответ

5

Я думаю, вам просто нужно зарегистрировать JSR-310 (Java 8 Дата/Время) модуль:

https://github.com/FasterXML/jackson-datatype-jsr310/

поскольку ядро ​​Джексон не может полагаться на Java 8 функций (исходный уровень в этой точке, с 2.5, является Java 6). И в будущем поддержка большинства библиотек типов данных в любом случае будет проходить через подключаемые модули.

+0

Crap, я забыл упомянуть об этом ... но у меня есть этот модуль, включенный в мой pom.xml. Я обновлю свой вопрос с дополнительной информацией ... – HeinoVDS

8

Это сработало для меня, и я не использую Spring boot.

@Configuration 
@EnableWebMvc 
public class SpringMvcConfiguration extends WebMvcConfigurerAdapter { 

    @Override 
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { 
     Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); 
     builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); 
     converters.add(new MappingJackson2HttpMessageConverter(builder.build())); 
    } 
} 
+0

Добавлена ​​часть configureMessageConverters, так как она не будет работать без нее: p – Niclas

+0

Обязательно отключите 'SerializationFeature.WRITE_DATES_AS_TIMESTAMPS' не' SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS'. Они выглядят такими же, но только сперва работали. Отлаживали это в течение 2 часов. – Jaanus

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