2009-11-10 6 views
2

J'utilise JAXB pour la génération XML rapide et sale. J'ai une classe qui représente une structure arborescente:Existe-t-il un moyen de restreindre la profondeur de marshaling pour les graphiques d'objets dans JAXB?

@XmlRootElement(name = "element") 
public class Element { 

    // [...] 

    @XmlElementWrapper(name="childs") 
    @XmlElementRef 
    public List<Element> getChilds() { /*...*/ } 
} 

Je souhaite limiter la profondeur à laquelle la collection enfant est rassemblée. Ainsi, par exemple je voudrais écrire juste les enfants directs de l'élément que j'envoie au Marshaller mais omettre leurs enfants.

Existe-t-il un moyen JAXB standard pour ce faire ou peut-être un rappel que je peux utiliser pour désactiver le marshaling d'une propriété à la volée?

Répondre

1

Vous pouvez essayer d'utiliser l'annotation XmlJavaTypeAdapter et votre implémentation de l'interface XmlAdapter.

+0

J'ai déjà pensé à cela, mais je n'ai pas réussi à comprendre comment déclencher le triage JAXB des enfants depuis l'intérieur de l'adaptateur. Il n'y a pas d'accès au Marshaller via l'interface XmlAdapter, donc il semble que mes options sont: 1) pour en créer un nouveau, qui peut devenir un gros succès ou 2) avoir accès au Marshaller actuel - par exemple en utilisant un la classe de contexte ThreadLocal personnalisée - qui, je suppose, n'est pas sûre (ou même possible) car cela signifierait réutiliser le Marshaller pendant qu'un autre objet est encore en cours de traitement. – FRotthowe

+0

Vous pouvez utiliser un pool de Marshallers et les réutiliser. Dans tous les cas, il n'y en aura pas plus de 2 utilisés à la fois car vous n'avez vraiment besoin que de 2 niveaux. –

+0

Je vais essayer d'utiliser un pool de marshallers comme vous l'avez suggéré. Cela ne ressemble pas à une solution "propre", mais au moins il n'est pas nécessaire de modifier les classes du modèle. – FRotthowe

1

Si vous savez que vous ne comptez pas utiliser votre structure de données après marshaling ou vous pouvez facilement faire une copie, je définirais la fonction de rappel placier (http://java.sun.com/javase/6/docs/api/javax/xml/bind/Marshaller.html#marshalEventCallback):

boolean beforeMarshal(Marshaller); 

dans votre classe d'élément . Vous pouvez utiliser ce rappel d'événement pour suivre la profondeur atteinte par le marshaller. Quand il atteint la profondeur limite, annulez simplement la propriété enfant annotée. JAXB par défaut ne produit pas d'élément lorsqu'il rencontre une propriété null, donc le marshaller s'arrêtera là. Si vous voulez réutiliser votre structure après le marshalling, vous devez jouer à des jeux en déplaçant les enfants que vous ne voulez pas sérialisés dans une propriété non-annotée et en les déplaçant dans votre propriété principale après le marshaller:

void afterMmarshal(Marshaller); 

Ce modèle ajoute un peu d'odeur de conception parce que vous avez une méthode non annotée avec une signature magique qui est jamais appelé à partir de votre propre code, mais il fonctionne.

+0

Malheureusement, j'ai besoin de la structure de données après marshalling. En fait, les objets sont mappés en hibernation: toutes les modifications peuvent éventuellement être envoyées dans la base de données, donc les modifier directement semble un peu trop risqué. – FRotthowe