如何在JAXB中更改对象上的XmlRootElement的名称?

我有以下物品

电影

@Entity
@Table(name="film")
@XmlRootElement(name = "film")
public class Film implements Serializable {

    @Id
    @Column(name="id")
    private String fbId;

    @Column(name="title")
    private String title;

    @ManyToMany
    @JoinTable(
        name="direction",
        joinColumns={@JoinColumn(name="film", referencedColumnName="id")},
        inverseJoinColumns={@JoinColumn(name="person", referencedColumnName="id")})
    private Collection<Person> directors;

    @OneToMany(cascade={CascadeType.ALL}, mappedBy="film")
    @MapKey(name="character")
    private Map<String, Performance> performances;

    //GETTERS
    @XmlAttribute(name = "fbId")
    public String getFreebaseId() {
        return this.fbId;
    }

    @XmlElementRefs({
        @XmlElementRef(name="director", type=Person.class)
    })
    public Collection<Person> getDirectors() {
        return this.directors;
    }

    @XmlAnyElement(lax=true)
    public Collection<Performance> getPerformances() {
        ArrayList performancesArray = new ArrayList<Performance>();
        for (Map.Entry<String, Performance> entry : this.performances.entrySet()) {
            Performance value = entry.getValue();
            performancesArray.add(value);
        }
        return performancesArray;
    }

}

@Entity
@Table(name="person")
public class Person implements Serializable {

    @Id
    @Column(name="id")
    private String fbId;

    @Column(name="first_name")
    private String firstName;

    @Column(name="last_name")
    private String lastName;

    @OneToMany(cascade={CascadeType.ALL}, mappedBy="actor")
    @XmlTransient
    private Collection<Performance> performances;

    //GETTERS
    @XmlAttribute(name = "fbId")
    public String getFreebaseId() {
        return this.fbId;
    }

    @XmlElement(name = "firstName")
    public String getFirstName() {
        return this.firstName;
    }

    @XmlElement(name = "lastName")
    public String getLastName() {
        return this.lastName;
    }

    @XmlTransient
    public Collection<Performance> getPerformances() {
        return this.performances;
    }

}

每部电影都有一个(或许多)导演和表演,即“人物”.我不需要为导演上课,但我会为性能而做,因为他们有更多的信息.

性能

@Entity
@Table(name="performance")
@XmlRootElement(name = "performace")
public class Performance implements Serializable {

    @Id
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="film")
    private Film film;

    @Id
    @Column(name="film_character")
    private String character;

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="actor")
    private Person actor;

    //TO STRING
    public String toString() {
        return this.actor.toString() + " - " + this.character;
    }

    //GETTERS
    @XmlTransient
    public Film getFilm() {
        return this.film;
    }

    @XmlElementRefs({
        @XmlElementRef(name = "firstName", type = Person.class),
        @XmlElementRef(name = "lastName", type = Person.class)
    })
    public Person getActor() {
        return this.actor;
    }

    @XmlElement(name = "character")
    public String getCharacter() {
        return this.character;
    }

}

当我通过JAXB运行时,我得到了这个:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<film fbId="1">
    <description>Nice film</description>
    <person fbId="1">
        <firstName>Quentin</firstName>
        <lastName>Tarantino</lastName>
    </person>
    <performace>
        <person fbId="4">
            <firstName>Steve</firstName>
            <lastName>Buscemi</lastName>
        </person>
        <character>Billy</character>
    </performace>
    <performace>
        <person fbId="2">
            <firstName>Jhon</firstName>
            <lastName>Travolta</lastName>
        </person>
        <character>Vincent</character>
    </performace>
    <performace>
        <person fbId="3">
            <firstName>Samuel</firstName>
            <lastName>L Jackson</lastName>
        </person>
        <character>Jules</character>
    </performace>
    <performace>
        <person fbId="1">
            <firstName>Quentin</firstName>
            <lastName>Tarantino</lastName>
        </person>
        <character>Jimmie</character>
    </performace>
    <title>Pulp Fiction</title>
</film>

有没有办法改变“人”的名字?得到这样的东西:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<film fbId="1">
    <description>Nice film</description>
    <director fbId="1">
        <firstName>Quentin</firstName>
        <lastName>Tarantino</lastName>
    </director>
    <performace fbId="4">
        <firstName>Steve</firstName>
        <lastName>Buscemi</lastName>
        <character>Billy</character>
    </performace>
    <performace fbId="2">
        <firstName>Jhon</firstName>
        <lastName>Travolta</lastName>
        <character>Vincent</character>
    </performace>
    <performace fbId="3">
        <firstName>Samuel</firstName>
        <lastName>L Jackson</lastName>
        <character>Jules</character>
    </performace>
    <performace fbId="1">
        <firstName>Quentin</firstName>
        <lastName>Tarantino</lastName>
        <character>Jimmie</character>
    </performace>
    <title>Pulp Fiction</title>
</film>

最佳答案 选项:

> Make Director使用自己的@XmlRootElement扩展Person
>使用JAXBElement<?扩展人>而不是人

问题是,@ XmlElementRef.name对@XmlRootElement不起作用,读取here

If type() is JAXBElement.class , then namespace() and name() point to
a factory method with XmlElementDecl. The XML element name is the
element name from the factory method’s XmlElementDecl annotation or if
an element from its substitution group (of which it is a head element)
has been substituted in the XML document, then the element name is
from the XmlElementDecl on the substituted element.

If type() is not JAXBElement.class, then the XML element name is the
XML element name statically associated with the type using the
annotation XmlRootElement on the type. If the type is not annotated
with an XmlElementDecl, then it is an error.

If type() is not JAXBElement.class, then this value must be “”.

顺便说说

@XmlElementRefs({
    @XmlElementRef(name = "firstName", type = Person.class),
    @XmlElementRef(name = "lastName", type = Person.class)
})

对我来说似乎没有用. @XmlElementRef不应映射目标类的属性.

点赞