我可以忽略ObjectMapper中的MismatchedInputException吗?

时间:2018-10-16 14:08:23

标签: java json spring jackson objectmapper

我正在像这样使用Jackson ObjectMapper类:

objectMapper.treeToValue(jsonNode, MyClass.class)

其中jsonNodeJsonNode的实例。

当我致电treeToValue()时,我收到一条MismatchedInputException的消息

Cannot deserialize instance of com.example.MyField` out of START_OBJECT token

因为MyField被定义为MyClass内的字符串,但它是jsonNode变量内的JSON对象。我对jsonNode的其中一个字段具有不匹配的类型完全满意,但我宁愿ObjectMapper只是不尝试对该字段进行序列化并忽略它,而不是抛出{{1} }。

我尝试使用

MismatchedInputException

但这只是忽略缺少的字段,它并不能阻止现有字段的objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

2 个答案:

答案 0 :(得分:0)

在diginoise提到的帖子中,您应该查看一下此响应:

https://stackoverflow.com/a/40972234/9343066

答案 1 :(得分:0)

您可以递归删除有问题的字段,然后重试。这是我想出的(可以根据您的日志记录和异常处理需求进行简化)。

public class YourClass {

    private static final Logger LOGGER = Logger
            .getLogger(YourClass.class.getName());

    public final static ObjectMapper mapper = new ObjectMapper().configure(
            DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    public static <T> T toTypedObject(Class<T> type, JsonNode tree) {
        return toTypedObject(type, tree, true);
    }

    private static <T> T toTypedObject(Class<T> type, JsonNode tree,
            boolean topLevel) {

        T object;

        try {
            object = mapper.treeToValue(tree, type);
        } catch (MismatchedInputException e) {
            String originalTree = tree.toString();
            object = toTypedObject(type, tree, originalTree, e);
            if (topLevel) {
                LOGGER.log(Level.WARNING, "Failed to convert node tree to a "
                        + type.getSimpleName()
                        + " object without modifications: " + originalTree, e);
                LOGGER.log(Level.INFO,
                        "Modified node tree was successfully converted to a "
                                + type.getSimpleName() + " object: " + tree);
            }
        } catch (JsonProcessingException e) {
            throw new YourException("Failed to convert node tree to a "
                    + type.getSimpleName() + " object: " + tree, e);
        }

        return object;
    }

    private static <T> T toTypedObject(Class<T> type, JsonNode tree,
            String originalTree,
            MismatchedInputException mismatchedInputException) {

        T object;

        List<Reference> path = mismatchedInputException.getPath();
        if (path != null && !path.isEmpty()) {

            try {

                ObjectNode subNode = (ObjectNode) tree;
                for (int i = 0; i < path.size(); i++) {
                    String fieldName = path.get(i).getFieldName();
                    if (i + 1 < path.size()) {
                        subNode = (ObjectNode) tree.get(fieldName);
                    } else {
                        subNode.remove(fieldName);
                    }
                }
                object = toTypedObject(type, tree, false);

            } catch (Exception e) {
                throw new YourException("Failed to convert node tree to a "
                        + type.getSimpleName() + " object: " + originalTree,
                        mismatchedInputException);
            }

        } else {
            throw new YourException(
                    "Failed to convert node tree to a " + type.getSimpleName()
                            + " object: " + originalTree,
                    mismatchedInputException);
        }

        return object;
    }

}

致电:

YourObject yourObject = YourClass.toTypedObject(YourObject.class, tree);