Java 为什么';t设置Jackson将空列表接受为空工作?
我的公司有一个使用SpringWeb的JavaWeb服务,它通过RESTAPI接受JSON。我们使用的是Maven,我们的Jackson版本是2.9。我们试图防止在API不需要反序列化异常的情况下,当积分器传入空列表时引发反序列化异常 例如,下面是我的应用程序类:Java 为什么';t设置Jackson将空列表接受为空工作?,java,json,spring,web-services,jackson,Java,Json,Spring,Web Services,Jackson,我的公司有一个使用SpringWeb的JavaWeb服务,它通过RESTAPI接受JSON。我们使用的是Maven,我们的Jackson版本是2.9。我们试图防止在API不需要反序列化异常的情况下,当积分器传入空列表时引发反序列化异常 例如,下面是我的应用程序类: import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplicatio
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;
}
pom.xml包含所有默认依赖项,并添加以下内容:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
很好用。但是,如果任何字段(尽管在我们的特定情况下,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]
根据项目的页面,选项ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT应该可以为我们解决这个问题。我们已经尝试直接在ObjectMapper
配置对象和应用程序中设置此属性。属性使用以下行:
spring.jackson.deserialization.accept-empty-array-as-null-object=true
这两种方法似乎都没有效果。我们目前正在对容易出现此问题的字段使用@JsonDeserialize(using=MyCustomDeserializer.class)
注释来解决此问题。但是,我们希望能够让所有字段在默认情况下将空列表视为null
我们是否误解了配置选项并错误地使用了它?在我们的应用程序中,有没有办法将空列表视为空列表,如果有,我们如何才能做到这一点?映射被序列化为空列表
{ "k1": "v1", "k2": "v2"}
空映射被序列化为
{ }
在您的示例中,您尝试将表示空列表或数组的[]放在地图中,这就是Jackson抱怨的原因。简单地说,无法将空列表映射到映射中。
这也解释了为什么启用ACCEPT\u EMPTY\u ARRAY\u AS\u NULL\u对象没有效果
更新
我错了。Jackson可以将空数组映射到映射。
创建了一个使用spring.jackson.deserialization.accept empty array as null object=true属性的最小springboot示例,可以将空数组[]映射到映射
检查是否需要。对于本例,我的问题是示例应用程序
类中的@EnableWebMvc
注释。删除该注释使我能够成功地向端点发送一个空数组,然后端点将其作为空对象接收
注意
我原来的问题仍然存在于我公司的应用程序中,即使删除了注释。然而,这似乎是一个与冲突的不同设置的问题。接受空数组作为空对象
我不能直接用ObjectMapper
或简单的Spring Boot应用程序重现这一点。请提供一个。我将努力提供,但这需要一些时间。仅供参考:JsonInclude.Include.NON_EMPTY
仅影响序列化(编写JSON),而不影响反序列化(读取JSON)。@Savior抱歉让您久等了。我用我认为是reprex的东西更新了这个问题。我还不太会问问题,所以如果你需要更多,请告诉我。还有什么你没有给我们看的吗?我不能复制这个,即使在加入龙目舞之后。您是否正在声明一个不同的ObjectMapper
bean?这就是反序列化功能的全部目的。根据他们链接的文档:确定是否接受空数组值(“JSON中的[]”)作为具有数据绑定的常规POJO(“beans”)的空值:这在处理用PHP之类的语言编写的端点时非常有用,该语言的类型松散,可能将缺少的对象表示为空数组。@savior我认为您错了。请注意,示例中的bean使用映射,而JSON使用数组/列表。他们没有地图。Jackson的错误很明显。只要看一下源代码中的测试:。我遇到了完全相同的问题,删除@EnableWebMvc
的相同解决方案解决了这个问题。不知道为什么,也不知道注释的值是什么——不过,似乎其他一切都像预期的那样工作。
spring.jackson.deserialization.accept-empty-array-as-null-object=true
{ "k1": "v1", "k2": "v2"}
{ }