【发布时间】:2020-07-21 09:59:51
【问题描述】:
我的公司有一个使用 Spring Web 的 Java Web 服务,该服务通过 REST API 接受 JSON。我们正在使用 Maven,我们的 Jackson 版本是 2.9。我们正在尝试防止在我们的 API 不期望一个空列表时,当集成器传入一个空列表时引发反序列化异常。
例如,这是我的应用程序类:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@EnableWebMvc
@SpringBootApplication
public class ExampleApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(ExampleApplication.class, args);
}
}
Student.java 类:
import lombok.Data;
import java.util.Map;
@Data
public class Student {
private String firstName;
private String lastName;
private Map<String, String> classGrades;
}
学生控制器:
package com.example.example.controllers;
import com.example.example.models.Student;
import org.springframework.http.RequestEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.stream.Stream;
@RestController()
@RequestMapping(value = "/Students/", produces = "application/json")
public class StudentController {
@PostMapping(path = "")
public RequestEntity<Student> createNewStudent(@RequestBody Student student) {
return null;
}
}
application.properties:
spring.jackson.deserialization.accept-empty-array-as-null-object=true
pom.xml 包含所有默认依赖项,并添加了以下内容:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
所有其他项目文件都默认为 Spring 初始化程序生成的项目结构。预期的请求正文(使用 Postman 形成的 JSON):
{
"firstName": "Mark",
"lastName": "Twain",
"classGrades": {
}
}
工作得很好。但是,如果任何字段(尽管在我们的特定情况下,classGrades 字段)收到一个空列表,则会引发 Jackson 反序列化异常。失败的 JSON 请求示例:
{
"firstName": "Mark",
"lastName": "Twain",
"classGrades": []
}
以及抛出的异常:
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `java.util.LinkedHashMap` out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.LinkedHashMap` out of START_ARRAY token
at [Source: (PushbackInputStream); line: 65, column: 28]
根据项目的github 页面,ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT 选项应该可以为我们解决这个问题。我们尝试直接在ObjectMapper 配置对象和application.properties 中使用以下行进行设置:
spring.jackson.deserialization.accept-empty-array-as-null-object=true
这两种方法似乎都没有生效。我们目前正在对容易出现此问题的字段使用@JsonDeserialize(using = MyCustomDeserializer.class) 注释的解决方法。但是,我们希望能够让我们的所有字段默认将空列表视为 null。
我们是否误解了配置选项并错误地使用了它?有没有办法在我们的应用程序中将空列表视为 null,如果是,我们如何实现这一点?
【问题讨论】:
-
我无法直接使用
ObjectMapper重现此问题,也无法使用简单的 Spring Boot 应用程序。请提供minimal reproducible example。 -
我会努力提供这个,虽然这需要一些时间。
-
仅供参考:
JsonInclude.Include.NON_EMPTY只影响序列化(写入 JSON),不影响反序列化(读取 JSON)。 -
@Savior 抱歉让您久等了。我已经用我认为的代表更新了这个问题。我还是新手,所以如果您需要更多问题,请告诉我。
-
还有什么你没有给我们看的吗?即使添加了龙目岛,我也无法重现这一点。您是否可能声明了一个不同的
ObjectMapperbean?
标签: java json spring web-services jackson