给出以下 SampleTestClass,我尝试将 JSON 解析为 Java:
class EmptyListDeserializerTest {
final ObjectMapper objectMapper = new ObjectMapper();
{
objectMapper.configOverride(List.class)
.setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY, Nulls.AS_EMPTY));
}
@Test
void test2() throws JsonProcessingException {
final var result = objectMapper.readValue("null", new TypeReference<List<MyClass>>() {});
assertThat(result).isEmpty();
}
@Test
void test3() throws JsonProcessingException {
final var json = """
[{
"name": "John Doe",
"address": null
}]
""";
final var result = objectMapper.readValue(json, new TypeReference<List<MyComplexClass>>() {});
assertThat(result.get(0).address).isEmpty();
}
@Test
void test4() throws JsonProcessingException {
final var json = """
[{
"name": "John Doe"
}]
""";
final var result = objectMapper.readValue(json, new TypeReference<List<MyComplexClass>>() {});
assertThat(result.get(0).address).isEmpty();
}
public static class MyClass {
public MyClass() {
}
private String name;
public MyClass(final String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
}
public static class MyComplexClass {
public MyComplexClass() {
}
private String name;
private List<String> address;
public MyComplexClass(final String name, final List<String> address) {
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
public List<String> getAddress() {
return address;
}
public void setAddress(final List<String> address) {
this.address = address;
}
}
}
我想实现将所有类型的不存在列表映射到空列表。 调整实体本身并不是解决方案。 只有 ObjectMapper 具有适应性。
我尝试了各种可能的解决方案,但只设法让test3通过,所有其他都失败了。
我还尝试了 CustomerDeserializer,但它从未被调用,即使已注册:
public List<?> deserialize(JsonParser p, DeserializationContext ctxt)
那么,我错过了什么?
--- 编辑 ---
改用此配置:
{
objectMapper.configOverride(List.class)
.setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY, Nulls.AS_EMPTY));
SimpleModule module = new SimpleModule();
module.addDeserializer(List.class, new EmptyListDeserializer());
this.objectMapper.registerModule(module);
}
并稍微修改 test2 (添加转义双引号):
@Test
void test2() throws JsonProcessingException {
final var result = objectMapper.readValue("\"null\"", new TypeReference<List<MyClass>>() {});
assertThat(result).isEmpty();
}
测试 2 通过,但测试 3 失败。
CustomDeserializer 看起来像这样:
public class EmptyListDeserializer extends JsonDeserializer<List<?>> {
@Override
public List<?> deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
// Check for null or 'null' string value
if (p.getCurrentToken() == JsonToken.VALUE_NULL
|| p.getCurrentToken().isScalarValue()
|| (p.getCurrentToken() == JsonToken.VALUE_STRING && "null".equals(p.getText()))) {
return Collections.emptyList();
}
// Otherwise, proceed with default deserialization
return p.readValueAs(List.class);
}
test4
没有解决方案。 Jackson 通过 json 属性进行迭代,并且从不触及 json 中未提及的属性。
我在这里看到两个选项:
null
。test2
也不起作用。只需检查结果并将 null
替换为所需值即可。