2010-10-17 9 views
6

Lors de l'utilisation de JAXB avec Java-First, les champs/propriétés de type java.util.Date sont organisés et démasqués en tant que xs:dateTime et tout fonctionne comme prévu.Dire JAXB à unmarshal <xs:dateTime> à la classe Date à l'aide des annotations

Mais si le type du champ/propriété est Object, JAXB unmarshals xs:dateTime à XMLGregorianCalendarImpl.

Je dois trouver un moyen de rendre les valeurs de date-heure unmarshal JAXB à java.util.Date en utilisant des annotations. Sinon, je devrai passer en revue toutes les valeurs non-mémorisées dans chaque cas d'utilisation.

Même s'il y avait un after-unmarshall-hook à définir sur les classes contenant des champs d'objet et convertir les instances manuellement serait bon. Mais je ne pouvais pas trouver quelque chose qui puisse être utilisé de cette façon non plus.

Notez que j'ai un accès limité au contexte JAXB, car il est utilisé dans Apache CXF.

Répondre

4

Vous pouvez définir la propriété type sur @XmlElement.

@XmlElement(type=Date.class) 
public Object getGenericDateProperty() { 
    return date; 
} 

Edit:

Puisque vous ne connaissez pas le type que vous pouvez utiliser un XMLAdapter. Si la valeur unmarshalled est un XMLGregorianCalendar, convertissez-la en date. Pour plus d'informations sur XMLAdapter voir:

+0

L'objet n'est pas toujours une date. Cela peut être de différents types. Dans le XSD généré, il est spécifié en tant que xs: anyType. La date est l'une des valeurs possibles. – Iravanchi

+0

Vous pouvez écrire un XmlAdapter pour convertir entre les types de date. –

+0

J'ai un XmlAdapter pour la conversion entre XMLGregorianCalendar et Date, mais je ne peux pas l'appliquer à un champ de type Object en utilisant @XmlJavaTypeAdapter - il en résulte IllegalAnnotationException. – Iravanchi

5

En plus de la réponse de Blaise Doughan:

je pourrais enfin comprendre cela, grâce à l'aide de Blaise Doughan. En fait sa réponse fonctionne avec juste un petit changement: s'il y a plusieurs types qui doivent être unmarshalled comme la propriété Object, il doit y avoir plusieurs annotations @XmlElement placées dessus en utilisant l'annotation @XmlElements.

Voici mon code maintenant:

@XmlElements 
     ({ 
       @XmlElement(name = "dateValue", type = Date.class), 
       @XmlElement(name = "stringValue", type = String.class), 
       @XmlElement(name = "booleanValue", type = Boolean.class), 
       @XmlElement(name = "listValue", type = ArrayList.class), 
       @XmlElement(name = "bytesValue", type = Byte[].class) 
     }) 
public Object getFieldValue() 
{ 
    return fieldValue; 
} 

Note: spécifier « nom » est nécessaire pour que cela fonctionne, car il devrait y avoir un moyen pour le placier/unmarshaller pour identifier le type de contenu.

Il y a deux questions mineures ici:

  1. Vous devez spécifier une liste de tous les types attendus (ce qui est logique, étant donné le cas de rassemblement)

  2. Il n'y a pas moyen de spécifiez un seul nom pour cette propriété. Dans mon cas, où JAXB est utilisé dans les services Web CXF, le code généré à partir de WSDL dans .NET nomme ce champ "Item". S'il y avait un moyen, par exemple, d'envelopper les éléments XML dans un autre qui a un nom unique, le code généré pourrait être un peu plus agréable.