强制 Jackson 将 LocalDate 序列化为数组

aun*_*low 5 java spring json date jackson

我正在使用 spring-boot 2.1.6 并且有一个 API 可以接受包含日期的表单,例如:

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

@Controller
public class MyController {
    @PostMapping("...")
    public ResponseEntity<...> post(@RequestBody MyForm myForm) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

默认情况下,spring MVC 接受这种 JSON 格式:

{
   "date": [2020, 6, 17],
   ...
}
Run Code Online (Sandbox Code Playgroud)

所以在前端,我的 JavaScript 代码只是提交一个这样的表单,即 JS 会将日期转换为数组。

但是当我运行 spring-boot 测试时,这个序列化不起作用,代码如下:

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

Run Code Online (Sandbox Code Playgroud)

这是因为 Jackson 默认将 LocalDate 序列化为:

{
    "date": {
        "year":2020,
        "month":"JUNE",
        "monthValue":6,
        ...
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

如此处所述:LocalDate Serialization: date as array? ,有很多配置可以强制 spring-boot 将数据序列化为 format yyyy-MM-dd。但我不想改变我的 JS 代码。我只是想让我的测试用例工作。

如何配置ObjectMapper以强制 Jackson 将 LocalDate 序列化为数组?我只想得到这个:

{
   "date": [2020, 6, 17],
   ...
}
Run Code Online (Sandbox Code Playgroud)

更新

LocalDate这是java.time.LocalDate但不是org.joda.time.LocalDate

Mic*_*ber 4

您需要注册JavaTimeModule。Maven 依赖:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
Run Code Online (Sandbox Code Playgroud)

示例,如何使用它:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码打印:

{"value":[2020,6,17]}
Run Code Online (Sandbox Code Playgroud)

也可以看看: