我正在将Spring-boot REST API应用程序中的某些模型转换为使用Java 8 java.time.LocalDateTime而不是joda的模型DateTime。我希望从API调用返回的时间戳遵循该ISO_8601格式。动机是要与Java8的时间向前兼容
java.time.LocalDateTime
DateTime
ISO_8601
事实证明,困难的部分是序列化包含LocalDateTimeJSON 的对象。
LocalDateTime
例如,我有以下实体:
// ... misc imports import java.time.LocalDateTime; import java.time.ZoneOffset; @Data @Entity @Table(name = "users") public class User { @Id @Column private String id; @Column private String name; @Column private String email; @Column @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss", timezone = "UTC") private java.time.LocalDateTime createdAt; public User(String name, String email) { this.id = Utils.generateUUID(); this.createdAt = LocalDateTime.now(ZoneOffset.UTC); } }
我还设置了application.properties关闭日期作为时间戳杰克逊功能:
application.properties
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS = false
我的行家部门:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>1.3.6.RELEASE</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> <version>2.8.1</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.0.1.Final</version> </dependency>
最后,我尝试通过控制器检索JSON表示形式:
@RequestMapping("/users") @RestController public class UserController { private UserService userService; @Autowired public UserController(UserService userService) { this.userService = userService; } @RequestMapping( value = "/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE ) public User getUser(@PathVariable("id") String id) { return userService.findById(id); } }
当我实际调用此端点时,出现以下异常:
java.lang.NoSuchMethodError: com.fasterxml.jackson.datatype.jsr310.ser.JSR310FormattedSerializerBase.findFormatOverrides(Lcom/fasterxml/jackson/databind/SerializerProvider;Lcom/fasterxml/jackson/databind/BeanProperty;Ljava/lang/Class;)Lcom/fasterxml/jackson/annotation/JsonFormat$Value;
另外,我还在ObjectMapper配置类中配置了应用程序:
ObjectMapper
@Configuration public class ServiceConfiguration { @Bean public ObjectMapper getJacksonObjectMapper() { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.registerModule(new JavaTimeModule()); objectMapper.configure( com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false ); return objectMapper; } }
任何线索将不胜感激。
事实证明,这是Spring Boot的Jackson版本与我的版本中的版本不匹配pom.xml。正如Miloš和Andy所建议的那样,一旦我设置了正确的版本并使用运行应用程序spring.jackson.serialization.write_dates_as_timestamps=true,问题就解决了,而无需ObjectMapper在LocalDateTime模型字段上配置或添加注释。
pom.xml
spring.jackson.serialization.write_dates_as_timestamps=true
... <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>1.3.6.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>1.3.6.RELEASE</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> </dependency> </dependencies>
这NoSuchMethodError是因为您正在混合Jackson的版本。Spring Boot 1.3.6使用Jackson 2.6.7,而您使用的是2.8.1 jackson-datatype-jsr310。
NoSuchMethodError
jackson-datatype-jsr310
Spring Boot为Jackson提供了依赖项管理,包括jackson-datatype- jsr310,因此您应该从pom中删除该版本。如果要使用其他版本的Jackson,则应覆盖该jackson.version属性:
jackson-datatype- jsr310
jackson.version
<properties> <jackson.version>2.8.1</jackson.version> </properties>
这将确保您所有的Jackson依赖项都具有相同的版本,从而避免版本不匹配的问题。
您也可以根据需要删除配置的Java代码ObjectMapper。Java时间模块在类路径中时会自动注册,并写入日期,因为可以在以下位置配置时间戳application.properties:
spring.jackson.serialization.write-dates-as-timestamps=false