Могу ли я игнорировать MismatchedInputException в ObjectMapper? - PullRequest
0 голосов
/ 16 октября 2018

Я использую класс Джексона ObjectMapper примерно так:

objectMapper.treeToValue(jsonNode, MyClass.class)

, где jsonNode - это экземпляр JsonNode .

Когда я вызываю treeToValue(), я получаю MismatchedInputException с сообщением

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

, потому что MyField определяется как строка внутри MyClass, но это объект JSON внутриjsonNode переменная.У меня все в порядке с jsonNode, имеющим несоответствующий тип для одного из его полей, но я бы предпочел ObjectMapper просто не пытаться сериализовать это поле и игнорировать его вместо того, чтобы выдавать MismatchedInputException.

Я пытался использовать

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

, но это просто игнорирует пропущенные поля, оно ничего не делает для предотвращения MismatchedInputException для существующего поля.

Ответы [ 2 ]

0 голосов
/ 02 июля 2019

Вы можете рекурсивно удалить ошибочные поля и повторить попытку.Вот то, что я придумал (можно упростить на основе ваших потребностей в ведении журналов и обработке исключений).

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);
0 голосов
/ 16 октября 2018

В сообщении, на которое ссылается дигиноз, вы должны взглянуть на этот ответ:

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

...