Java 8 LocalDateTime 为 JsonString 抛出异常
Java 8 LocalDateTime throwing exception for JsonString
我正在测试控制器的 spring- 启动代码。为此,我编写了如下测试
@RunWith(SpringRunner.class)
@WebMvcTest(AnimalController.class)
class AnimalControllerTest {
@Autowired
MockMvc mvc;
@MockBean
AnimalService animalService;
@Test
void addAnimal() throws Exception {
AnimalDto animalDto = new AnimalDto();
mvc.perform(MockMvcRequestBuilders
.post("/animal/add")
.content(asJsonString(new AnimalDto(null, "dog", LocalDateTime.now(),null, null, null, null)))
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.jsonPath("$.id").exists());
}
}
private String asJsonString(Object animalDto) {
try {
return new ObjectMapper().writeValueAsString(animalDto);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
但我遇到了以下错误
java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: com.self.zoo.dto.AnimalDto["located"])
at com.self.zoo.controller.AnimalControllerTest.asJsonString(AnimalControllerTest.java:63)
at com.self.zoo.controller.AnimalControllerTest.addAnimal(AnimalControllerTest.java:50)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: com.self.zoo.dto.AnimalDto["located"])
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
但我在我的类路径中看到我也看到了 JSR-310 jar Java faster-json-Java8 jar。
在下面添加是否有maven依赖:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-modules-java8</artifactId>
<version>2.13.3</version>
<type>pom</type>
<scope>runtime</scope>
</dependency>
您需要使用 ObjectMapper 实例显式注册 JavaTimeModule。
@Bean
public ObjectMapper mapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
return mapper;
}
可以参考https://github.com/FasterXML/jackson-modules-java8#usage
用注解
注解你的属性
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
这是一个完整答案的问题:
在您的代码中,您使用的是新实例化的 ObjectMapper
,它没有注册所有模块。而是使用 Spring Boot 提供的 pre-configured ObjectMapper
。您可以 @Autowired
将其放入您的测试中以使用它。
@Autowired
private ObjectMapper mapper;
private String asJsonString(Object animalDto) {
try {
return mapper.writeValueAsString(animalDto);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
在您的依赖项中,您不需要添加 jackson-datatype-jsr310
和 jackson-modules-java8
。默认情况下,这些已经由 Spring Boot 提供并自动配置。所以删除那些依赖项。
我正在测试控制器的 spring- 启动代码。为此,我编写了如下测试
@RunWith(SpringRunner.class)
@WebMvcTest(AnimalController.class)
class AnimalControllerTest {
@Autowired
MockMvc mvc;
@MockBean
AnimalService animalService;
@Test
void addAnimal() throws Exception {
AnimalDto animalDto = new AnimalDto();
mvc.perform(MockMvcRequestBuilders
.post("/animal/add")
.content(asJsonString(new AnimalDto(null, "dog", LocalDateTime.now(),null, null, null, null)))
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.jsonPath("$.id").exists());
}
}
private String asJsonString(Object animalDto) {
try {
return new ObjectMapper().writeValueAsString(animalDto);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
但我遇到了以下错误
java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: com.self.zoo.dto.AnimalDto["located"])
at com.self.zoo.controller.AnimalControllerTest.asJsonString(AnimalControllerTest.java:63)
at com.self.zoo.controller.AnimalControllerTest.addAnimal(AnimalControllerTest.java:50)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: com.self.zoo.dto.AnimalDto["located"])
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
但我在我的类路径中看到我也看到了 JSR-310 jar Java faster-json-Java8 jar。
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-modules-java8</artifactId>
<version>2.13.3</version>
<type>pom</type>
<scope>runtime</scope>
</dependency>
您需要使用 ObjectMapper 实例显式注册 JavaTimeModule。
@Bean
public ObjectMapper mapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
return mapper;
}
可以参考https://github.com/FasterXML/jackson-modules-java8#usage
用注解
注解你的属性@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
这是一个完整答案的问题:
在您的代码中,您使用的是新实例化的 ObjectMapper
,它没有注册所有模块。而是使用 Spring Boot 提供的 pre-configured ObjectMapper
。您可以 @Autowired
将其放入您的测试中以使用它。
@Autowired
private ObjectMapper mapper;
private String asJsonString(Object animalDto) {
try {
return mapper.writeValueAsString(animalDto);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
在您的依赖项中,您不需要添加 jackson-datatype-jsr310
和 jackson-modules-java8
。默认情况下,这些已经由 Spring Boot 提供并自动配置。所以删除那些依赖项。