Разница в JSON Сериализация атрибута OffsetDateTime при использовании Spring Boot и Jackson ObjectMapper - PullRequest
0 голосов
/ 28 марта 2020

Когда я начал писать тесты для моего REST API на основе Spring Boot, я заметил, что атрибут OffsetDateTime в моем DTO сериализуется по-разному, использую ли я Spring Mock MVC для выполнения запроса или Jackson ObjectMapper. При использовании 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 Mock MVC выглядит следующим образом:

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

В то время как fooDTO JSON из ObjectMapper выглядит следующим образом:

{"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 вернет тот же результат, что и Mock MVC, и использую мою аннотацию в DTO , Я был бы очень признателен за помощь в этом, даже если решение было бы достаточно очевидным. Я не слишком привык работать в экосистеме Java, особенно в Spring.

1 Ответ

1 голос
/ 28 марта 2020

Решением, которое привело к ожидаемому результату, было добавление библиотеки jackson-modules-java8 (в моем случае я думаю, что она уже присутствовала из-за Spring (-Boot) или другой зависимости моего приложения) и добавьте соответствующий модуль в картограф Джексона. Рабочее решение для получения «правильной» строки JSON было:

String fooDTOJSON = new ObjectMapper().registerModule(new JavaTimeModule()).writeValueAsString(fooDTO);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...