2010-04-19 9 views
2

Nous avons ce XML:Représentant l'élément comme booléen avec JAXB?

<Summary> 
    <ValueA>xxx</ValueA> 
    <ValueB/> 
    </Summary> 

<ValueB/> aura jamais d'attributs ou des éléments internes. C'est un élément de type booléen - il existe (vrai) ou pas (faux). JAXB a généré une classe Summary avec un membre String valueA, ce qui est bon. Mais pour ValueB, JAXB a généré une classe interne et un membre correspondant ValueB:

@XmlElement(name = "ValueB") 
protected Summary.ValueB valueB; 

Mais ce que je voudrais est membre boolean et pas classe interne:

@XmlElement(name = "ValueB") 
protected boolean valueB; 

Comment pouvez-vous faire ce?

Je ne cherche pas à régénérer les classes, je voudrais juste faire le code changer manuellement.


Mise à jour: Conformément à la réponse acceptée, nous avons créé une nouvelle méthode renvoyant la valeur booléenne conditionnelle si valeurB == null. Comme nous utilisons Hibernate, nous avons annoté valueB avec @Transient et annoté le getter booléen avec l'annotation @Column de Hibernate.

+0

Avez-vous vraiment besoin d'un champ booléen? Pourquoi pas seulement les méthodes booléennes getter/setter? – skaffman

+0

Yup, c'est ce que nous avons fait .. –

Répondre

1

Il est JAXB tout à fait logique crée une classe interne car il pense que c'est un commplexAttribute

Au lieu de changer à un booléen, vous pouvez également vérifier null == valueB si vous mettez

@XmlElement(name = "ValueB", nillable='true') protected Summary.ValueB valueB; dans votre logique.

ou d'ajouter un getter supplémentaire qui n'a pas @XMl .... et renvoie l'état de valeur calculéB peut-être ce que vous voulez est possible avec JAXB Je n'en avais pas besoin auparavant.

+0

Yup, ça marcherait. Je préférerais ne pas avoir la classe interne .. serait plus simple. –

6

Utilisez un XmlAdaptor:

package com.example.xml.adaptor; 
import javax.xml.bind.annotation.adapters.XmlAdapter; 

public class BooleanToEmptyObjectAdapter extends XmlAdapter<EmptyObject, Boolean> { 
    @Override 
    public EmptyObject marshal(final Boolean v) { 
     return v != null && v ? new EmptyObject() : null; 
    } 

    @Override 
    public Boolean unmarshal(final EmptyObject v) { 
     return true; 
    } 
} 

Et un objet factice pour qu'il sérialisation:

package com.example.xml.adaptor; 

public class EmptyObject { 
    // EMPTY 
} 

Ensuite, dans votre objet, utilisez un Boolean (pas boolean) terrain:

@XmlRootElement(name = "FooElement") 
public class Foo { 

    @XmlElement() 
    @XmlJavaTypeAdapter(BooleanToEmptyObjectAdapter.class) 
    private final Boolean isPresent = false; 

    ... 
    // You might need to @XmlTransient your getter/setter, or JAXB might complain about redefinition 
    @XmlTransient 
    public boolean isPresent() { 
     return this.isPresent; 
    } 
} 

Cela devrait produire <isPresent/> élément vrai, mais o mit-le quand c'est faux.

+0

Annoter @XmlAccessorType (XmlAccessType.NONE) sur la classe puis le @XmlTransient n'est pas nécessaire, seules les propriétés explicitement annotées seront prises en compte. –

+0

Il convient également de mentionner que le getter et les setters doivent avoir l'objet booléen comme type de retour (pour le getter) et le type de paramètre (pour le setter) ...en utilisant le type primitif sur l'un ou l'autre ou les deux n'a pas fonctionné pour moi. –

Questions connexes