简体   繁体   English

捕获异常后不终止反序列化过程

[英]Not terminate deserialization process after caught exception

Below is an example of my json :以下是我的 json 示例:

[
    {
        firstKey : "value1",
        secondKey : "value2"
    },
    {
        firstKey : "value3",
        secondKey : "value4"
    }
]

I am deserializing the api response (json) to java object using Jackson Object Mapper.我正在使用 Jackson Object Mapper 将 api 响应(json)反序列化为 java 对象。

However, while deserializing, when the JSON object returned has extra key (not present in POJO), the whole program terminates.但是,在反序列化时,当返回的 JSON 对象具有额外的键(POJO 中不存在)时,整个程序将终止。 I want the code to deserialize all the JSON Objects inside the JSONARRAY and then throw all the exceptions at the end.我希望代码反序列化 JSONARRAY 中的所有 JSON 对象,然后在最后抛出所有异常。

One way to achieve this would be to create a custom deserializer that loops the Json array/list and inspects each item individually at the same time collecting possible errors.实现这一点的一种方法是创建一个自定义反序列化器,它循环 Json 数组/列表并在收集可能的错误的同时单独检查每个项目。

First we would need models to describe Json structure.首先,我们需要模型来描述 Json 结构。 First the actual item:首先是实际项目:

@Getter @Setter
public class KeyHolder {
    private String firstKey;
    private String secondKey;
}

Then a simple helper class to represent the list adn make the code a bit cleaner:然后是一个简单的辅助类来表示列表并使代码更简洁:

@SuppressWarnings("serial")
@JsonDeserialize(using = KeyHolderListDeserializer.class )
public class KeyHolderList extends ArrayList<KeyHolder> {}

Note the annotation @JsonDeserialize m it will then trigger the custom deserializer shown below:请注意@JsonDeserialize m 注释,然后它将触发如下所示的自定义反序列化器:

public class KeyHolderListDeserializer extends JsonDeserializer<KeyHolderList> {
    // This is just an example exception how you could wrap the exceptions to one
    @SuppressWarnings("serial")
    @RequiredArgsConstructor
    public static class ValidationException extends RuntimeException {
        @Getter
        private final Map<Integer, Exception> failedObjects;
    }

    @Override
    public KeyHolderList deserialize(JsonParser p, DeserializationContext ctxt) 
            throws IOException, JsonProcessingException {
        KeyHolderList readObjects = new KeyHolderList();
        Map<Integer, Exception> failedObjects = new HashMap<>();
        ObjectMapper om = new ObjectMapper();
        int i = 0;
        // Read values first as tree ignoring type and validness
        TreeNode listNode = p.readValueAsTree();
        for (; i < listNode.size(); i++) {
            TreeNode itemNode = listNode.get(i);
            try {
                // Then in this loop try to instantiate each one indivually
                // storing the succeeded ones...
                readObjects.add(om.treeToValue(itemNode, KeyHolder.class));
            } catch (Exception e) {
                // ... and reporting the failing ones
                failedObjects.put(i, e);
            }
        }
        // Finally you can do liek below or whatever you need to do with the results
        if(failedObjects.isEmpty()) {
            return readObjects;            
        }
        throw new ValidationException(failedObjects);
    }

}

After these it is just:在这些之后,它只是:

KeyHolderList keyHolderList = om.readValue(YOUR_JSON_SOURCE, KeyHolderList.class);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM