es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Campos incorrectos de Json

¿Cómo puedo obtener todos los nombres de campos incorrectos? Por ejemplo, tengo la siguiente cadena de entrada en formato JSON:

{
“name”: “name#1”,
“address”: “address#1”,
“pone”: “000000000”,
“ail”: “mail@smth.ru”
}

Donde los campos ‘pone’ y ‘ail’ son incorrectos. Se necesita usar ‘phone’ y ’email’. También uso esta propiedad:

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);

Para capturar la excepción. Y la atrapo dentro de un try/catch cuando deserializo JSON a un objeto, pero solo hay información sobre un campo en el mensaje de excepción.

Necesito obtener todos los campos incorrectos de una vez.

Quizás alguien tenga una idea al respecto. También intenté usar jsonSchema, pero creo que no es una buena idea porque al final tengo este mensaje “$: se encontró una cadena, se esperaba un objeto” con este código:

JsonSchemaFactory factory = JsonSchemaFactory.getInstance (VersionFlag.V201909);
InputStream stream=TestClass.class.getResourceAsStream(“/file.json”);
JsonSchema schema=factory.getSchema(stream);
JsonNode node =mapper.convertToJsonNode(MyObject.builder().build());
Set validationResult = schema.validate(node);

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para obtener todos los nombres de campo incorrectos de una vez, puede utilizar una implementación personalizada de JsonParser, que le permitirá capturar todos los errores durante la fase de análisis. Aquí se presenta una implementación de ejemplo:

    import com.fasterxml.jackson.core.JsonLocation;
    import com.fasterxml.jackson.core.JsonParser;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.core.JsonToken;
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    public class WrongFieldNamesParser extends JsonParser {
    
        private final ObjectMapper mapper;
        private final JsonParser parser;
        private final List<string> wrongFields;
    
        public WrongFieldNamesParser(ObjectMapper mapper, JsonParser parser) {
            this.mapper = mapper;
            this.parser = parser;
            this.wrongFields = new ArrayList<>();
        }
    
        public List<string> getWrongFields() {
            return wrongFields;
        }
    
        @Override
        public boolean isClosed() {
            return parser.isClosed();
        }
    
        @Override
        public ObjectCodec getCodec() {
            return parser.getCodec();
        }
    
        @Override
        public void setCodec(ObjectCodec c) {
            parser.setCodec(c);
        }
    
        @Override
        public Version version() {
            return parser.version();
        }
    
        @Override
        public void close() throws IOException {
            parser.close();
        }
    
        @Override
        public JsonToken nextToken() throws IOException, JsonProcessingException {
            JsonToken token = parser.nextToken();
            if (token == JsonToken.FIELD_NAME) {
                String name = parser.getCurrentName();
                if (!validateFieldName(name)) {
                    wrongFields.add(name);
                }
            }
            return token;
        }
    
        private boolean validateFieldName(String name) {
            // Validate the field name against a list of expected names
            // You can customize this logic based on your requirements
            return name.equals("name") || name.equals("address") || name.equals("phone") || name.equals("email");
        }
    
        @Override
        public JsonParser skipChildren() throws IOException, JsonProcessingException {
            return parser.skipChildren();
        }
    
        @Override
        public boolean isExpectedStartArrayToken() {
            return parser.isExpectedStartArrayToken();
        }
    
        @Override
        public boolean isExpectedStartObjectToken() {
            return parser.isExpectedStartObjectToken();
        }
    
        @Override
        public boolean hasTokenId(int id) {
            return parser.hasTokenId(id);
        }
    
        @Override
        public boolean hasToken(JsonToken t) {
            return parser.hasToken(t);
        }
    
        @Override
        public JsonToken currentToken() {
            return parser.currentToken();
        }
    
        @Override
        public int currentTokenId() {
            return parser.currentTokenId();
        }
    
        @Override
        public boolean hasCurrentToken() {
            return parser.hasCurrentToken();
        }
    
        @Override
        public boolean canUseSchema(FormatSchema schema) {
            return parser.canUseSchema(schema);
        }
    
        @Override
        public boolean canReadObjectId() {
            return parser.canReadObjectId();
        }
    
        @Override
        public boolean canReadTypeId() {
            return parser.canReadTypeId();
        }
    
        @Override
        public Object getObjectId() throws IOException, UnsupportedOperationException {
            return parser.getObjectId();
        }
    
        @Override
        public JsonLocation getTokenLocation() {
            return parser.getTokenLocation();
        }
    
        @Override
        public JsonLocation getCurrentLocation() {
            return parser.getCurrentLocation();
        }
    
        @Override
        public String getCurrentName() throws IOException, JsonProcessingException {
            return parser.getCurrentName();
        }
    
        @Override
        public void clearCurrentToken() {
            parser.clearCurrentToken();
        }
    
        @Override
        public JsonToken getLastClearedToken() {
            return parser.getLastClearedToken();
        }
    
        @Override
        public void overrideCurrentName(String name) {
            parser.overrideCurrentName(name);
        }
    }
    

    Para utilizar esta implementación, puede pasar su cadena JSON de entrada al WrongFieldNamesParser y comprobar la lista wrongFieldspara obtener todos los nombres de campo incorrectos. Aquí hay un ejemplo de código:

    import com.fasterxml.jackson.core.JsonParser;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException;
    
    import java.io.IOException;
    
    public class Main {
    
        public static void main(String[] args) {
            String input = "{\n" +
                    "    \"name\": \"name#1\",\n" +
                    "    \"address\": \"address#1\",\n" +
                    "    \"pone\": \"000000000\",\n" +
                    "    \"ail\": \"mail@smth.ru\"\n" +
                    "}";
            ObjectMapper mapper = new ObjectMapper();
            try {
                WrongFieldNamesParser parser = new WrongFieldNamesParser(mapper, mapper.getFactory().createParser(input));
                mapper.readValue(parser, Object.class);
                System.out.println(parser.getWrongFields());
            } catch (IOException e) {
                if (e instanceof UnrecognizedPropertyException) {
                    System.out.println(((UnrecognizedPropertyException) e).getPropertyName());
                    // Maneje la excepción
                } else {
                    e.printStackTrace();
                }
            }
        }
    }
    

    Este código producirá la salida: [pone, ail].

Comments are closed.