Force Jackson serialize LocalDate to Array

蹲街弑〆低调 提交于 2020-12-10 08:42:27

问题


I'm using spring-boot 2.1.6 and there is an API to accept a form including a date like:

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

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

By default spring MVC accept this JSON format:

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

So in Front-End, my JavaScript code just submit a form like this, i.e. JS will convert a date to an array.

But when I run spring-boot test, this serialization does not work, with the following code:

    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();
        ...
    }

This is because Jackson by default serialize LocalDate as:

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

As mentioned here: LocalDate Serialization: date as array? , there are many configurations to force spring-boot serialize data as format yyyy-MM-dd. But I don't want to change my JS code. I just want to make my test case work.

How can I configure ObjectMapper to force Jackson to serialize LocalDate to Array? I just want to get this:

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

UPDATE

LocalDate here is java.time.LocalDate but not org.joda.time.LocalDate.


回答1:


You need to register JavaTimeModule. Maven dependency:

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

Example, how to use it:

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;
    }
}

Above code prints:

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

See also:

  • jackson-modules-java8
  • Jackson Serialize Instant to Nanosecond Issue
  • Jackson deserialize elasticsearch long as LocalDateTime with Java 8



回答2:


You could try to create a custom deserializer for LocalDate

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

And then register it by adding a Module bean. From the documentation:

Any beans of type com.fasterxml.jackson.databind.Module are automatically registered with the auto-configured Jackson2ObjectMapperBuilder and are applied to any ObjectMapper instances that it creates. This provides a global mechanism for contributing custom modules when you add new features to your application.

@Bean
public Module LocalDateDeserializer() {
    SimpleModule module = new SimpleModule();
    module.addDeserializer(LocalDate.class, new LocalDateDeserializer());
    return module;
}



回答3:


you can bulid a converter that gets the date value an returns the wanted array. this will be your entity

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

your converter

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

      @Override
      public String[] convert(Date value) {
          //logic for pushing data into Array and return it
      }
    }


来源:https://stackoverflow.com/questions/62423389/force-jackson-serialize-localdate-to-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!