场景描述
- 需求
需求主要是将前端通过json传上来的时间,通过@RequestBody自动绑定到Bean里的LocalDateTime成员上。
- 绑定方法
使用@JsonFormat 注解,示例:@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
- 出现问题的版本
我使用Spring Boot 2.0.0 时,直接在字段上加上@JsonFormat 注解就可以完成数据的绑定。
而在使用Spring Boot 1.5.8时,只在字段上加上@JsonFormat 注解,在数据绑定时就会报错。
- 报错信息
w.s.m.s.DefaultHandlerExceptionResolver :
Failed to read HTTP message:
org.springframework.http.converter.HttpMessageNotReadableException:
JSON parse error:
Can not construct instance of java.time.LocalDateTime:
no String-argument constructor/factory method to deserialize from String value ('2018-04-12 14:00:16');
nested exception is com.fasterxml.jackson.databind.JsonMappingException:
Can not construct instance of java.time.LocalDateTime:
no String-argument constructor/factory method to deserialize from String value ('2018-04-12 14:00:16')
at [Source: java.io.PushbackInputStream@5cf71c5b; line: 9, column: 17]
(through reference chain:
com.semonx.gateway.comm.entity.ErrCodePushVo["errcodepushList"]
->java.util.ArrayList[0]
->com.semonx.gateway.comm.entity.ErrCodePushSon["happentime"])
解决方法
添加Jackson对Java Time的支持后,就能解决这个问题。
在pom.xml中添加:
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-parameter-names</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
添加JavaConfig,自动扫描新添加的模块:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.fasterxml.jackson.databind.ObjectMapper;
@Configuration
public class JacksonConfig {
@Bean
public ObjectMapper serializingObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.findAndRegisterModules();
return objectMapper;
}
}
或者在application.properties添加如下配置:spring.jackson.serialization.write-dates-as-timestamps=false
或者只注册JavaTimeModule,添加下面的Bean
@Bean
public ObjectMapper serializingObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.registerModule(new JavaTimeModule());
return objectMapper;
}
参考资料
新的Jackson模块:https://github.com/FasterXML/jackson-modules-java8
其他人遇到的类似的情况:http://www.jb51.net/article/136389.htm