Pudiera darse el caso de que halles algún problema con tu código o proyecto, recuerda probar siempre en un entorno de testing antes aplicar el código al proyecto final.
Solución:
Aquí hay una solución aproximada pero más declarativa. No he podido reducirlo a una sola anotación, pero esto parece funcionar bien. Tampoco estoy seguro sobre el rendimiento en grandes conjuntos de datos.
Dado este JSON:
"list": [
"wrapper":
"name": "Jack"
,
"wrapper":
"name": "Jane"
]
Y estos objetos modelo:
public class RootObject
@JsonProperty("list")
@JsonDeserialize(contentUsing = SkipWrapperObjectDeserializer.class)
@SkipWrapperObject("wrapper")
public InnerObject[] innerObjects;
y
public class InnerObject
@JsonProperty("name")
public String name;
Donde se implementa el vudú de Jackson como:
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotation
public @interface SkipWrapperObject
String value();
y
public class SkipWrapperObjectDeserializer extends JsonDeserializer
¡Espero que sea útil para alguien!
Sus datos son problemáticos porque tiene información interna envoltura objetos en tu array. Presumiblemente tu Vendor
objeto está diseñado para manejar id
, name
, company_id
pero cada uno de esos múltiples objetos también está envuelto en un objeto con una sola propiedad vendor
.
Supongo que estás usando el Jackson El enlace de datos modelo.
Si es así, hay dos cosas a considerar:
El primero es usar una propiedad de configuración especial de Jackson. Jackson – desde 1.9 creo, esto puede no estar disponible si está usando una versión anterior de Jackson – proporciona UNWRAP_ROOT_VALUE
. Está diseñado para casos en los que sus resultados están envueltos en un objeto de propiedad única de nivel superior que desea descartar.
Entonces, juega con:
objectMapper.configure(SerializationConfig.Feature.UNWRAP_ROOT_VALUE, true);
El segundo es usar objetos de envoltura. Incluso después de descartar el objeto de envoltorio externo, todavía tiene el problema de su Vendor
objetos que se envuelven en un objeto de propiedad única. Use un envoltorio para evitar esto:
class VendorWrapper
Vendor vendor;
// gettors, settors for vendor if you need them
Del mismo modo, en lugar de utilizar UNWRAP_ROOT_VALUES
, también podría definir una clase contenedora para manejar el objeto externo. Suponiendo que tienes la correcta Vendor
, VendorWrapper
objeto, puede definir:
class VendorsWrapper
List vendors = new ArrayList();
// gettors, settors for vendors if you need them
// in your deserialization code:
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readValue(jsonInput, VendorsWrapper.class);
El árbol de objetos para VendorsWrapper es análogo a su JSON:
VendorsWrapper:
vendors:
[
VendorWrapper
vendor: Vendor,
VendorWrapper:
vendor: Vendor,
...
]
Finalmente, podrías usar el Jackson modelo de árbol para analizar esto en JsonNodes
descartando el nodo exterior, y para cada JsonNode
en el ArrayNode
llamando:
mapper.readValue(node.get("vendor").getTextValue(), Vendor.class);
Eso podría resultar en menos código, pero no parece menos torpe que usar dos contenedores.
@Patrick, mejoraría un poco tu solución
@Override
public Object deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
ObjectNode objectNode = jp.readValueAsTree();
JsonNode wrapped = objectNode.get(wrapperKey);
JsonParser parser = node.traverse();
parser.setCodec(jp.getCodec());
Vendor mapped = parser.readValueAs(Vendor.class);
return mapped;
Funciona más rápido 🙂
Te mostramos comentarios y valoraciones
Si posees algún reparo y capacidad de acrecentar nuestro escrito te mencionamos escribir una acotación y con placer lo leeremos.