Jackson无法反序列化空字节数组/流

u5i3ibmn  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(119)

我能以某种方式改变ObjectMapper以能够处理空值和空值吗?
假设我的值读作

objectMapper.readValue(val, new TypeReference<Object>() {});

其中瓦尔为

val = new ByteArrayInputStream(new byte[] {});

我无法控制传递的值,也无法在执行readValue之前检查缓冲区长度。
我尝试过使用DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT配置Map器,例如:

mapper.configure(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true);

但是我还是得到了com.fasterxml.jackson.databind.exc.MismatchedInputException: No content to map due to end-of-input错误。有没有可能以某种方式让Jackson忽略空值而只返回null?

lnxxn5zx

lnxxn5zx1#

有没有可能让Jackson忽略空值而只返回null?
通过使用更低级的流API,可以成功地使用空字节数组或空输入流进行拨号。
这就是在将数据输入到ObjectMapper之前,如何通过使用JsonParser来确保有一些数据需要解析的核心思想:

byte[] jsonBytes1 = {};
        
ObjectMapper mapper = new ObjectMapper();
JsonParser parser = mapper.getFactory().createParser(jsonBytes1);

JsonNode node = parser.readValueAsTree();
        
MyPojo myPojo = null;
        
if (node != null) {
    myPojo = mapper.treeToValue(node, MyPojo.class);
}

因此,我们将输入解析为JsonNode,并手动检查它,只有当它不为空时,ObjectMapper才起作用。
如果我们把这个逻辑提取到一个单独的方法中,它可能看起来像这样(Java 8Optional在这种情况下可能是一个方便的返回类型):

public static <T> Optional<T> convertBytes(byte[] arr,
                                           Class<T> pojoClass,
                                           ObjectMapper mapper) throws IOException {
    
    JsonParser parser = mapper.getFactory().createParser(arr);
    JsonNode node = parser.readValueAsTree();
    
    return node != null ? Optional.of(mapper.treeToValue(node, pojoClass)) : Optional.empty();
}

用法示例

考虑一个简单的POJO:

public class MyPojo {
    private String name;
    
    // getter, setters and toString
}

main()

public static void main(String[] args) throws IOException {

    String source = """
        {
            "name" : "Alice"
        }
        """;
    
    byte[] jsonBytes1 = {};
    byte[] jsonBytes2 = source.getBytes(StandardCharsets.UTF_8);
    
    ObjectMapper mapper = new ObjectMapper();
    
    System.out.println(convertBytes(jsonBytes1, MyPojo.class, mapper));
    System.out.println(convertBytes(jsonBytes2, MyPojo.class, mapper));
}
  • 输出:*
Optional.empty
Optional[Test.MyPojo(name=Alice)]

相关问题