MOXy de la désérialisation d'exception: Un descripteur par défaut de l'élément racine n'a pas été trouvé dans le projet
Voici mes classes:
@XmlRootElement(name="Zoo")
class Zoo {
//@XmlElementRef
public Collection<? extends Animal> animals;
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({Bird.class, Cat.class, Dog.class})
@XmlDiscriminatorNode("@type")
abstract class Animal {
@XmlElement
public String name;
}
@XmlDiscriminatorValue("Bird")
@XmlRootElement(name="Bird")
class Bird extends Animal {
@XmlElement
public String wingSpan;
@XmlElement
public String preferredFood;
}
@XmlDiscriminatorValue("Cat")
@XmlRootElement(name="Cat")
class Cat extends Animal {
@XmlElement
public String favoriteToy;
}
@XmlDiscriminatorValue("Dog")
@XmlRootElement(name="Dog")
class Dog extends Animal {
@XmlElement
public String breed;
@XmlElement
public String leashColor;
}
Voici le JSON sérialisé:
{
"animals": [
{
"type": "Bird",
"name": "bird-1",
"wingSpan": "6 feets",
"preferredFood": "food-1"
},
{
"type": "Cat",
"name": "cat-1",
"favoriteToy": "toy-1"
},
{
"type": "Dog",
"name": "dog-1",
"breed": "bread-1",
"leashColor": "black"
}
]
}
Ici est la de-sérialiseur code:
public static <T> T Deserialize_Moxy(String jsonStr, Class<?>[] cl) throws JAXBException {
InputStream is = new ByteArrayInputStream(jsonStr.getBytes());
JAXBContext jc = JAXBContext.newInstance(cl);
Unmarshaller unmarshaller = jc.createUnmarshaller();
//Marshal to JSON
unmarshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json");
unmarshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, false);
@SuppressWarnings("unchecked")
T obj = (T)unmarshaller.unmarshal(is);
return obj;
}
Ici est l'exception:
Exception in thread "main" javax.xml.bind.UnmarshalException
- with linked exception:
[Exception [EclipseLink-25008] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: A descriptor with default root element was not found in the project]
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.handleXMLMarshalException(JAXBUnmarshaller.java:1014)
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:147)
at com.bp.samples.json.generics.Foo.Deserialize_Moxy(Foo.java:271)
at com.bp.samples.json.generics.Foo.main(Foo.java:111)
Caused by: Exception [EclipseLink-25008] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: A descriptor with default root element was not found in the project
at org.eclipse.persistence.exceptions.XMLMarshalException.noDescriptorWithMatchingRootElement(XMLMarshalException.java:143)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshallerHandler.startElement(SAXUnmarshallerHandler.java:222)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parseRoot(JSONReader.java:161)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:118)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:827)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:350)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:334)
at org.eclipse.persistence.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:407)
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:133)
... 2 more
Aussi une question sur le JSON sérialisé: Est-il un moyen pour obtenir le sérialiseur JSON de publier "@type" au lieu de "type". Actuellement, il semble que les objets ayant la propriété "type". Si l'on pouvait décorer avec "@", il sera plus évident qu'il s'agit plus d'un type d'info qu'une propriété.
Grâce,
Behzad
Vous devez vous connecter pour publier un commentaire.
Ci-dessous sont mes réponses à vos deux questions:
Question #1 - Exception
Lorsque vous utilisez le
MarshallerProperties.JSON_INCLUDE_ROOT
propriété pour désactiver les éléments racines, alors vous devez utiliser l'un desunmarshal
des méthodes qui prennent unClass
paramètre à dire MOXy le type d'objet que vous souhaitez unmarshal.Question #2
La
@
préfixe indique qu'un champ/cartes de propriété d'un attribut XML. Vous pouvez utiliser leJAXBContextProperties.JSON_ATTRIBUTE_PREFIX
propriété pour spécifier un préfixe de qualifier les données qui a été associé à un attribut XML.EXEMPLE COMPLET
Démo
d'entrée.json/Sortie
MODÈLE DE DOMAINE
Je ne recommande pas d'utiliser des champs publics dans votre modèle de domaine, mais si vous allez de cette façon, vous pouvez réduire vos métadonnées le suivant:
Zoo
Animal
Oiseau
jaxb.propriétés
Pour spécifier MOXy que votre JAXB (JSR-222) fournisseur, vous devez inclure un fichier appelé
jaxb.properties
dans le même package que votre modèle de domaine avec l'entrée suivante:@
préfixe. J'ai mis à jour ma réponse à inclure le document JSON.{ "animals" :
et la}
à la fin? donc, dans cette façon de déplier la liste?