valor una texto segĂșn segun otra funcion formato filas dependiendo condicionales condicional con colorear color celda cambiar java json jackson pojo

java - una - Requisito de campo condicional basado en otro valor de campo en Jackson?



formulas condicionales en excel=si y (2)

Considere una representación JSON con una cadena y dos matrices. Por ejemplo,

{ "type" : "A", "ListA" : [] "ListB" : [3, 4, 5] }

En el caso anterior, type es un campo obligatorio, pero ListA y ListB se requieren condicionalmente para la deserialización en función del valor del type . En otras palabras, ListA solo es obligatorio si el type tiene el valor A y el ListB solo es obligatorio si el type tiene un valor B

Actualmente, estoy trabajando en Jackson y en Java, y he podido implementar la obligatoriedad de hacer que el type campo sea obligatorio creando POJO siguiente manera:

public class Example { @JsonProperty(required = true) String type; // getter and setter auto-generated

Pero no puedo adjuntar otra @JsonProperty(required = true) a ListA o ListB ya que depende del valor de type .

¿Cómo puedo exigir condicionalmente ListA y ListB para la deserialización basada en el valor del type ?

Además, realizaré comprobaciones adicionales, como si ListA o ListB es una matriz vacía ( size == 0 ) o no.


Con Jackson puede crear su propio deserializador personalizado para su POJO de ejemplo, extender la clase StdDeserializer y anular el método deserialize () con su lógica. Aquí puede verificar el tipo y el tamaño de la lista.

Luego, para usar su deserializador personalizado, debe agregarlo a un SimpleModule y registrar este último con su Jackson ObjectMapper.

Hace un par de artículos escribí sobre este tema, donde puedes encontrar un ejemplo concreto sobre Serialización / Deserialización personalizada con Jackson:

Jackson: crea y registra un serializador JSON personalizado con las clases StdSerializer y SimpleModule

Jackson: crea un deserializador JSON personalizado con las clases StdDeserializer y JsonToken


Puede usar un deserializador personalizado para lograrlo.

Definiendo tu modelo

Tu clase de Example sería como:

public class Example { private String type; private List<Integer> listA; private List<Integer> listB; // Getters and setters omitted }

Creando un deserializador personalizado

Su deserializador personalizado podría ser lo siguiente:

public class ExampleDeserializer extends StdDeserializer<Example> { private static final String TYPE_A = "A"; private static final String TYPE_B = "B"; public ExampleDeserializer() { super(Example.class); } @Override public Example deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { ObjectMapper mapper = (ObjectMapper) p.getCodec(); JsonNode tree = mapper.readTree(p); Example example = new Example(); JsonNode typeNode = tree.get("type"); if (typeNode == null || typeNode.asText().isEmpty()) { throw ctxt.mappingException("/"type/" is required"); } example.setType(typeNode.asText()); switch (typeNode.asText()) { case TYPE_A: ArrayNode listANode = (ArrayNode) tree.get("ListA"); if (listANode == null || listANode.size() == 0) { throw ctxt.mappingException( "/"ListA/" is required when /"type/" is /"" + TYPE_A + "/""); } example.setListA(createList(listANode)); break; case TYPE_B: ArrayNode listBNode = (ArrayNode) tree.get("ListB"); if (listBNode == null || listBNode.size() == 0) { throw ctxt.mappingException( "/"ListB/" is required when /"type/" is /"" + TYPE_B + "/""); } example.setListB(createList(listBNode)); break; default: throw ctxt.mappingException( "/"type/" must be /"" + TYPE_A + "/" or /"" + TYPE_B + "/""); } return example; } private List<Integer> createList(ArrayNode arrayNode) { List<Integer> list = new ArrayList<Integer>(); for (JsonNode node : arrayNode) { list.add(node.asInt()); } return list; } }

Registrar el deserializador personalizado

Registre el deserializador personalizado definido anteriormente en su ObjectMapper :

SimpleModule module = new SimpleModule("ExampleDeserializer", new Version(1, 0, 0, null, "com.example", "example-deserializer")); ExampleDeserializer exampleDeserializer = new ExampleDeserializer(); module.addDeserializer(Example.class, exampleDeserializer); ObjectMapper mapper = new ObjectMapper() .registerModule(module) .enable(SerializationFeature.INDENT_OUTPUT);

Probando su deserializador personalizado

Use el serializador personalizado:

String json = "{/"type/":/"A/",/"ListA/":[1,2,3]}"; Example example = mapper.readValue(json, Example.class);