2010-09-16 15 views
3

Existe-t-il une annotation JAXB pour ignorer une classe parent lorsque vous avez un @XmlElement sur une liste des classes enfant? Juste pour clarifier - Je me demandais s'il y avait une meilleure façon que de marquer tous les getters/setters des classes parentes comme transitoires, puis de retourner aux classes enfant et d'ajouter des getters/setters et les annoter comme XmlElements ainsiIgnorer une classe parent lors de la sérialisation au format XML

exemple:

public class GenericHelper { 
    String name=""; 
    String dates=""; 
    String roleName=""; 
    String loe=""; 
    @XmlTransient 
    public String getName() {return name;} 
public void setName(String name) {this.name = name;} 
@XmlTransient 
public String getDates() {return dates;} 
public void setDates(String dates) {this.dates = dates;} 
@XmlTransient 
public String getRoleName() {return roleName;} 
public void setRoleName(String roleName) {this.roleName = roleName;} 
@XmlTransient 
public String getLOE() {return loe;} 
public void setLOE(String loe) { 
    this.loe = loe.replace("%", "").trim(); 
} 
} 

et

public class SpecificHelper extends GenericHelper { 
List<ProjectHelper> projects; 
public SpecificHelper(){ 
    projects=new ArrayList<ProjectHelper>(); 
} 
@XmlElement(name = "project") 
@XmlElementWrapper (name = "projectlist") 
public List<ProjectHelper> getProjects() {return projects;} 
public void setProjects(List<ProjectHelper> projects) {this.projects = projects;} 
@XmlElement 
public String getName(){ 
    return super.getName(); 
} 

@Override 
public String toString(){ 
    String ret="SpecificHelper ["; 
    ret+="name:"+name+";"; 
    ret+="dates:"+dates+";"; 
    ret+="roleName:"+roleName+";"; 
    ret+="loe:"+loe+";"; 
    ret+="\n\tprojects:"+projects+";"; 
    return ret+"]"; 
} 
} 

ainsi, dans cet exemple, si je prends les annotations XmlTransient i n GenericHelper, n'importe quelle classe qui l'étend, si je devais avoir une méthode getSpecificHelper() qui retourne une liste de tous les employeurs, et l'annote avec XmlElement, TOUS ces éléments retourneront avec un nom, LOE, RoleName, etc. Je cherche une annotation de classe pour aller sur GenericHelper afin que je puisse éviter d'avoir à utiliser tous les @XmlTransients individuellement, et seulement utiliser les notations XmlElement que j'ai mises dans le SpecificHelper

+0

Je ne suis pas sûr que je comprends. Est-il possible d'afficher un court exemple pour démontrer votre question? –

+0

sure..typing il maintenant – Derek

Répondre

4

Que penses-tu?

la classe parente

Nous utiliserons XmlAccessType.NONE pour dire JAXB que seuls les champs explicitement annotés/propriétés sont mises en correspondance.

import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 

@XmlAccessorType(XmlAccessType.NONE) 
public class Parent { 

    private String parentProperty1; 
    private String parentProperty2; 

    public String getParentProperty1() { 
     return parentProperty1; 
    } 

    public void setParentProperty1(String parentProperty1) { 
     this.parentProperty1 = parentProperty1; 
    } 

    public String getParentProperty2() { 
     return parentProperty2; 
    } 

    public void setParentProperty2(String parentProperty2) { 
     this.parentProperty2 = parentProperty2; 
    } 

} 

La classe enfant

Nous utiliserons XmlAccessType.PROPERTY sur l'enfant. Toutes les propriétés de la classe parente que nous voulons inclure devront être remplacées et être explicitement annotées. Dans cet exemple, nous allons introduire parentProperty2 de la classe Parent. Vous aurez seulement besoin de remplacer le getter de la classe parente.

import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.PROPERTY) 
public class Child extends Parent { 

    private String childProperty; 

    @Override 
    @XmlElement 
    public String getParentProperty2() { 
     return super.getParentProperty2(); 
    } 

    public String getChildProperty() { 
     return childProperty; 
    } 

    public void setChildProperty(String childProperty) { 
     this.childProperty = childProperty; 
    } 

} 

Classe de démonstration

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Marshaller; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Child.class); 

     Child child = new Child(); 
     child.setParentProperty1("parentProperty1"); 
     child.setParentProperty2("parentProperty2"); 
     child.setChildProperty("childProperty"); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(child, System.out); 
    } 
} 

de sortie

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<child> 
    <childProperty>childProperty</childProperty> 
    <parentProperty2>parentProperty2</parentProperty2> 
</child> 
+0

Je ne l'ai pas fait exactement comme vous l'avez dit ici, mais près. Merci pour les conseils! – Derek

+0

Que diriez-vous de la classe parente est dans la bibliothèque de tiers, et nous ne pouvons pas modifier son code source? – CaiNiaoCoder

+0

@CaiNiaoCoder - Si vous utilisez EclipseLink MOXy comme fournisseur JAXB, vous pouvez utiliser le document de mappage externe pour ce cas d'utilisation: http://blog.bdoughan.com/2010/12/extending-jaxb-representing-annotations.html –