Estoy usando Jackson clase ObjectMapper así:

objectMapper.treeToValue(jsonNode, MyClass.class)

Donde jsonNode es una instancia de JsonNode.

Cuando llamo a treeToValue(), obtengo un MismatchedInputException con el mensaje

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

Porque MyField se define como una cadena dentro de MyClass, pero es un objeto JSON dentro de la variable jsonNode. Estoy perfectamente de acuerdo con que jsonNode tenga un tipo que no coincida para uno de sus campos, pero prefiero ObjectMapper simplemente no intentar serializar este campo e ignorarlo en lugar de lanzar el {{X5} }.

He intentado usar

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

Pero esto simplemente ignora los campos faltantes, no hace nada para evitar el MismatchedInputException para un campo existente.

4
user2121620 16 oct. 2018 a las 17:08

2 respuestas

La mejor respuesta

Puede eliminar de forma recursiva los campos infractores e intentarlo de nuevo. Esto es lo que se me ocurrió (se puede simplificar en función de sus necesidades de registro y manejo de excepciones).

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;
    }

}

Llamar con:

YourObject yourObject = YourClass.toTypedObject(YourObject.class, tree);
0
bosborn 2 jul. 2019 a las 16:12

En la publicación a la que se refirió diginoise, deberías echar un vistazo a esta respuesta:

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

1
João Gonçalves 16 oct. 2018 a las 15:35