【发布时间】:2016-12-02 09:24:05
【问题描述】:
我正在将 spring-boot REST API 应用程序中的一些模型转换为使用 java 8 的 java.time.LocalDateTime 而不是 joda 的 DateTime。我希望从 API 调用返回的时间戳遵循 ISO_8601 格式。动机是向前兼容 Java 8 的时代 (more here)。
证明困难的部分是将包含LocalDateTime 的对象序列化为JSON。
例如,我有以下实体:
// ... 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 以关闭日期作为时间戳杰克逊功能:
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS = false
我的 Maven 部门:
<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:
@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 模型字段上添加注释。
...
<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>
【问题讨论】:
标签: serialization spring-boot java-8 jackson java-time