gpt4 book ai didi

java - 使用 Spring Boot 和 Jackson ObjectMapper 时 OffsetDateTime 属性的 JSON 序列化差异

转载 作者:行者123 更新时间:2023-12-02 08:49:04 29 4
gpt4 key购买 nike

当我开始为基于 Spring Boot 的 REST API 编写测试时,我注意到无论我使用 Spring MockMVC 执行请求还是使用 Jackson ,DTO 中的 OffsetDateTime 属性的序列化方式都不同>对象映射器。使用 Spring 时,我的 @JSONFormat 注释使用正确,但使用 ObjectMapper 时则不然。

@EqualsAndHashCode
@Builder
public class FooDTO{
public int id;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
public OffsetDateTime arrival;

public fooDTO(int id, OffsetDateTime arrival){
this.id = id;
this.arrival = arrival;
}
}

@RestController
public class FooController {
@Autowired
private FooRepository fooRepository;

@RequestMapping(value = "/foo/bar/{id}")
public fooDTO getFoo (@PathVariable int id) {
return fooRepository.loadDTO(id);
}
}

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = Application.class)
@WebMvcTest(FooController.class)
public class FooControllerTest {
@Autowired
private MockMvc mockMvc;

@MockBean
private FooRepository fooRepository;

@Test
public void fooTest() {
FooDTO fooDTO = FooDTO.builder().id(1).arrival(OffsetDateTime.now()).build();
String fooDTOJSON = new ObjectMapper().writeValueAsString(fooDTO);
when(fooRepository.loadDTO(1).thenReturn(fooDTO);
String reponse = mockMvc.perform(request(HttpMethod.GET, "/foo/bar/1").accept(APPLICATION_JSON).andReturn().getResponse().getContentAsString();
assertEquals(fooDTOJSON, response);
}

Spring MockMVC 响应如下所示:

{"id":1, "arrival": "2020-03-28 12:29:44"}

虽然来自 ObjectMapper 的 fooDTOJSON 看起来像这样:

{"id":1, "arrival":{"offset":{"totalSeconds":3600,"id":"+01:00","rules":{"fixedOffset":true,"transitions":[],"transitionRules":[]}},"nano":697162400,"year":2020,"monthValue":3,"dayOfMonth":28,"hour":12,"minute":29,"second":44,"dayOfWeek":"SATURDAY","dayOfYear":88,"month":"MARCH"}}

理想情况下,我希望 ObjectMapper 返回与 MockMVC 相同的结果,并在 DTO 上使用我的注释。我真的很感谢有人对此提供帮助,即使解决方案可能很明显。我不太习惯在 Java 生态系统中工作,尤其是 Spring。

最佳答案

导致预期结果的解决方案是添加 jackson-modules-java8库(在我的例子中,我认为由于 Spring(-Boot) 或我的应用程序的另一个依赖项,它已经存在)并将相应的模块添加到 Jackson Mapper。接收“正确”JSON 字符串的工作解决方案是:

String fooDTOJSON = new ObjectMapper().registerModule(new JavaTimeModule()).writeValueAsString(fooDTO);

关于java - 使用 Spring Boot 和 Jackson ObjectMapper 时 OffsetDateTime 属性的 JSON 序列化差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60901005/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com