Spring web: преобразование @RequestBody Json для Java8 LocalTime не работает

В моем веб-приложении Spring REST я пытаюсь заставить контроллер работать с Java8 LocalTime. Я отправляю этот Json в POST-запросе

{
    "hour": "0",
    "minute": "0",
    "second": "0",
    "nano": "0"
}

и я получаю HttpMessageNotReadableException со следующей ошибкой Джексона

Could not read JSON: No suitable constructor found for type [simple type, class java.time.LocalTime]: can not instantiate from JSON object (need to add/enable type information?) 
at [Source: org.apache.catalina.connector.CoyoteInputStream@58cfa2a0; line: 2, column: 5]; 
nested exception is com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class java.time.LocalTime]: can not instantiate from JSON object (need to add/enable type information?) 
at [Source: org.apache.catalina.connector.CoyoteInputStream@58cfa2a0; line: 2, column: 5]

Я использую spring-web-4.0.3.RELEASE с spring-boot-starter-web-1.0.2.RELEASE, jackson-databind-2.4.2 и jackson-datatype-jsr310-2.4.2.

Из того, что я понял, погуглив, Spring должен автоматически регистрировать модули JSR-310 для объектов Java8.time.

Я нашел ответ на свою проблему, но он у меня не работает: Spring Boot и Jackson, JSR310 в теле ответа

У меня нет конфигураций, аннотированных с помощью @EnableWebMvc, и вот мой единственный класс конфигурации

@EnableAutoConfiguration
@ComponentScan
@EnableAspectJAutoProxy()
@Configuration
@ImportResource(value = "Beans.xml") 
public class Application extends WebMvcConfigurerAdapter {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new StringToLocalDateTime());
        registry.addConverter(new LocalDateTimeToString());
        registry.addConverter(new StringToLocalDate());
        registry.addConverter(new LocalDateToString());
        registry.addConverter(new StringToLocalTime());
        registry.addConverter(new LocalTimeToString());
    }
}

Можете подсказать, что не так в моей конфигурации?


person Ste    schedule 10.12.2014    source источник
comment
Люди нашли время, чтобы помочь вам и ответить. Пожалуйста, найдите время, чтобы принять ответ.   -  person Matt Byrne    schedule 19.03.2015


Ответы (3)


В вашей конфигурации нет ничего плохого.

Я предлагаю вам обновить Spring Boot до версии 1.2.0.RELEASE. Он использует пакеты Spring 4.1.3, в которых решена проблема с MappingJackson2HttpMessageConverter. Чтобы получить дополнительную информацию, прочитайте: https://github.com/spring-projects/spring-boot/issues/1620#issuecomment-58016018 . Это сработало в моем случае.

Если вы не хотите обновлять версию Spring Boot, возможно, самое меньшее, что вы можете сделать, это явно аннотировать поля LocalTime следующим образом:

@JsonSerialize(using = DateTimeSerializer.class)
@JsonDeserialize(using = DateTimeDeserializer.class)
private LocalTime date;
person AdamBat    schedule 24.12.2014

Вам нужно зарегистрировать модуль как Bean для Spring, чтобы увидеть его и установить.

@Configuration
public class JacksonConfiguration {

    @Bean
    public JSR310Module jsr310Module() {
        return new JSR310Module();
    }
}
person Fabricio Colombo    schedule 23.12.2014
comment
Если вы используете SpringBoot, достаточно просто добавить банку в путь к классам (через Maven или Gradle). SpringBoot увидит его в пути к классам и автоматически использует. - person DavidR; 06.11.2015

С SpringBoot 1.5 я использовал следующую зависимость и работает из коробки!

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
person Jana    schedule 13.06.2017