Заставить Джексона сериализовать LocalDate в массив - PullRequest
2 голосов
/ 17 июня 2020

Я использую spring -boot 2.1.6, и есть API для принятия формы, включающей дату, например:

@Data
public class MyForm {
    private LocalDate date;
    ...
}

@Controller
public class MyController {
    @PostMapping("...")
    public ResponseEntity<...> post(@RequestBody MyForm myForm) {
        ...
    }
}

По умолчанию spring MVC принимает этот JSON формат:

{
   "date": [2020, 6, 17],
   ...
}

Итак, в Front-End мой код JavaScript просто отправляет такую ​​форму, т.е. JS преобразует дату в массив.

Но когда я запускаю spring- загрузочный тест, эта сериализация не работает со следующим кодом:

    private ObjectMapper mapper = new ObjectMapper();

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void doTest() {
        MyForm form = ...
        MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/...").
                contentType("application/json").content(mapper.writeValueAsString(form)).andReturn();
        ...
    }

Это потому, что Джексон по умолчанию сериализует LocalDate как:

{
    "date": {
        "year":2020,
        "month":"JUNE",
        "monthValue":6,
        ...
    }
    ...
}

Как упоминалось здесь: LocalDate Сериализация: дата в виде массива? , существует множество конфигураций для принудительной сериализации данных при загрузке Spring в формате yyyy-MM-dd. Но я не хочу менять свой код JS. Я просто хочу, чтобы мой тестовый пример работал.

Как я могу настроить ObjectMapper, чтобы Джексон сериализовал LocalDate в массив? Я просто хочу получить это:

{
   "date": [2020, 6, 17],
   ...
}

ОБНОВЛЕНИЕ

LocalDate вот java.time.LocalDate, но не org.joda.time.LocalDate.

Ответы [ 3 ]

1 голос
/ 17 июня 2020

Вам необходимо зарегистрироваться JavaTimeModule. Зависимость Maven:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

Пример, как его использовать:

import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import java.time.LocalDate;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        JsonMapper mapper = JsonMapper.builder()
                .addModule(new JavaTimeModule())
                .build();
        mapper.writeValue(System.out, new MyForm());
    }
}

class MyForm {

    private LocalDate value = LocalDate.now();

    public LocalDate getValue() {
        return value;
    }

    public void setValue(LocalDate value) {
        this.value = value;
    }
}

Код выше выводит:

{"value":[2020,6,17]}

См. Также:

0 голосов
/ 17 июня 2020

Вы можете попробовать создать собственный десериализатор для LocalDate

class LocalDateDeserializer extends StdDeserializer<LocalDate> {
    @Override
    public LocalDate deserialize(JsonParser parser, DeserializationContext context)
                throws IOException, JsonProcessingException {
       // implement;
    }
}

, а затем зарегистрировать его, добавив bean-компонент Module. Из документации :

Любые bean-компоненты типа com.faster xml .jackson.databind.Module автоматически регистрируются в автоматически настраиваемом Jackson2ObjectMapperBuilder и применяются к любому ObjectMapper экземпляры, которые он создает. Это обеспечивает глобальный механизм для добавления пользовательских модулей при добавлении новых функций в приложение.

@Bean
public Module LocalDateDeserializer() {
    SimpleModule module = new SimpleModule();
    module.addDeserializer(LocalDate.class, new LocalDateDeserializer());
    return module;
}
0 голосов
/ 17 июня 2020

вы можете создать конвертер, который получает значение даты и возвращает требуемый массив. это будет ваша сущность

@JsonSerialize(converter=DateToArray.class)
 private LocalDate date;

ваш конвертер

    @Component
    public class DateToArray extends StdConverter< Date, String[]> {

      @Override
      public String[] convert(Date value) {
          //logic for pushing data into Array and return it
      }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...