web-dev-qa-db-fra.com

Exclusion de champs dans JAXB

J'ai 2 classes:

@XmlRootElement
public class A {

    private Long id;
    private B b;

    // setters and getters
}

et

@XmlRootElement
public class B {

    private Long id;
    private String field1;
    private String field2;

    // setters and getters
}

Par défaut, si je transforme une instance de classe A en XML, j'aurai tous ses champs (id) et les champs de classe B référencés (id, field1, field2) comme ça:

<a>
    <id>2</id>
    <b>
        <id>5</id>
        <field1>test1</field1>
        <field2>test3</field2>
    </b>
</a>

Est-il possible de modifier quoi les champs de la classe référencée B sont inclus dans le XML de la classe A? Par exemple. Je veux dire que lorsque je transforme une instance de la classe A, je veux juste obtenir id de la classe B (pas de field1 et field2 champs), donc je veux obtenir:

<a>
    <id>2</id>
    <b>
        <id>5</id>
    </b>
</a>

Je ne veux pas annoter définitivement la classe B (en utilisant @XMLTransient ou @XMLElement) pour y parvenir, car il y a des cas où je veux exporter toute la classe B telle quelle (avec id, field1 et field2.)
Je ne veux tout simplement pas exporter tous ces champs lorsque la classe B est référencée à partir de A.

Est-ce même possible avec JAX-B?

38
Piotr Nowicki

Vous pouvez utiliser @XmlTransient sur le terrain. De plus, les liaisons JAXB par défaut peuvent être remplacées à une portée globale ou au cas par cas selon les besoins en utilisant déclarations de liaisons personnalisées .

Consultez le Guide de JAXB du site Web de Baeldung pour plus d'exemples.

21

Vous pouvez utiliser l'annotation @XmlTransient pour ignorer les champs. Mettez cette annotation sur le champ lui-même ou son getter.

102
AlexR

Ok, j'ai trouvé une solution hacky:

@XmlRootElement
public class A {

    private Long id;
    private B b;

    // setters and getters
}

J'ai fourni un getter supplémentaire juste pour le cas d'utilisation REST, donc c'est comme:

@XMLTransient
public B getB() {
    return b;
}

@XMLElement(name="b")
public Long getBForREST() {
    return b.getId();
}

Il en résulte la structure suivante:

<a>
    <id>2</id>
    <b>5</b>
</a>

Ce n'est pas exactement la même structure que je visais, cela fonctionne pour moi.

Je n'aime pas cette solution - une @XMLExclude({"field1", "field2"}) ou quelque chose comme ça serait beaucoup plus propre à mon avis.

Néanmoins - pour l'instant, cela fonctionne; c'est moche, mais ça marche.

13
Piotr Nowicki