jackson xml désérialiser inline tableau
Comment désérialiser de ces étranges XML. À mon avis, les accessoires-entité est manquant (autour de la props), mais je ne peux pas changer la source de ce document XML (web service).
<parents>
<parent name="first">
<description><![CDATA[Description for the first-Entity]]></description>
<prop name="level">
<value><![CDATA[1]]></value>
</prop>
<prop name="enabled">
<value><![CDATA[true]]></value>
</prop>
<prop name="version">
<value><![CDATA[1.0-beta3]]></value>
</prop>
</parent>
<parent name="second">...</parent>
...
</parents>
Mes entités sont
public class Test {
@Test
public void deserializerTest() throws JsonParseException, JsonMappingException, IOException {
ObjectMapper om = new XmlMapper();
List<Parent> xml = om.readValue(new File("./test.xml"),
new TypeReference<List<Parent>>() {});
}
}
public class Prop {
@JacksonXmlProperty(isAttribute = true)
public String name;
@JacksonXmlText
public String value;
}
@JacksonXmlRootElement
public class Parent {
@JacksonXmlProperty(isAttribute = true)
public String name;
public String description;
//1. alternative with List
public List<Prop> prop;
//2. alternative with Map
@JsonDeserialize(using = PropDeser.class)
public Map<String, String> prop;
}
public static class PropDeser extends JsonDeserializer<Map<String, String>> {
@Override
public Map<String, String> deserialize(JsonParser jp,
DeserializationContext ctxt) throws IOException,
JsonProcessingException {
Map<String, String> ret = new HashMap<String, String>();
boolean eof = false;
while (jp.hasCurrentToken()) {
JsonToken t = jp.getCurrentToken();
switch (t) {
case END_OBJECT:
if (eof) {
return ret;
}
eof = true;
break;
case VALUE_STRING:
ret.put(jp.getCurrentName(), jp.getText());
break;
default:
eof = false;
break;
}
jp.nextValue();
}
return null;
}
}
1. Alternative
crée une exception " ne Peut pas instancier une valeur de type [type simple, classe de mon.test.Prop] de Chaîne JSON; pas une seule Chaîne de constructeur par défaut/méthode (à travers la chaîne de référence: ma.test.Parent["prop"])'
Je ne veux pas d'une simple liste de chaînes. J'ai besoin des deux: le nom et la valeur. Je suis donc venu à l'idée d'utiliser un Map<String, String>
en créant mon propre deserializer...
2. Alternative
L'erreur semble être la méthode PropDeser.deserialize() consomme de la fermeture de la balise de la société mère.
java.lang.NullPointerException
at com.fasterxml.jackson.databind.deser.impl.BeanPropertyMap.find(BeanPropertyMap.java:160)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:287)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:112)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:226)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:203)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:23)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2575)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1766)
at my.test.Test.deserializerTest(Test.java:57)
Est-il une possibilité d'itérer en arrière dans le XML-stream? Comment cette méthode peut-elle savoir quand s'arrêter? Je n'ai aucune idée.
Vous devez vous connecter pour publier un commentaire.
Il devrait être possible de gérer les "déballé" style des éléments d'une liste avec Jackson module XML 2.1, avec
@JacksonXmlElementWrapper(useWrapping=false)
.Structure doit être quelque chose comme ceci:
de sorte que votre solution est assez proche.
Noter que si les classes internes sont utilisés, ils doivent être "statique" dans la déclaration.
J'ai testé avec 2.1.4, et cela fonctionne pour moi.
JacksonXmlModule
il y a la méthodesetDefaultUseWrapper
.