简体   繁体   English

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

[英]How to change the name of the XmlRootElement in JAXB deppending on the object?

I have the following objects 我有以下物品

Film 电影

@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;
    }

}

Person

@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;
    }

}

Each film has one (or many) directors and performances which are "Persons". 每部电影都有一个(或许多)导演和表演,即“人物”。 I don't need a class for directors but I do for perfomances because they have more info. 我不需要为导演上课,但我会为性能而做,因为他们有更多的信息。

Performance 性能

@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;
    }

}

When I run this through JAXB I get this: 当我通过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>

Is there a way to change the name of the "person"? 有没有办法改变“人”的名字? To get something like this: 得到这样的东西:

<?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>

Options: 选项:

  • Make Director extends Person with its own @XmlRootElement Make Director使用自己的@XmlRootElement扩展Person
  • Use JAXBElement<? extends Person> 使用JAXBElement<? extends Person> JAXBElement<? extends Person> instead of Person JAXBElement<? extends Person>而不是Person

The problem is, @XmlElementRef.name does not work for @XmlRootElement , read here : 问题是,@ XmlElementRef.name不适用于@XmlRootElement ,请在此处阅读:

If type() is JAXBElement.class , then namespace() and name() point to a factory method with XmlElementDecl. 如果type()是JAXBElement.class,则namespace()和name()指向带有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. XML元素名称是工厂方法的XmlElementDecl批注中的元素名称,或者如果在XML文档中替换了其替换组中的元素(其为head元素),则元素名称来自替换的XmlElementDecl元件。

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. 如果type()不是JAXBElement.class,则XML元素名称是使用类型上的注释XmlRootElement与类型静态关联的XML元素名称。 If the type is not annotated with an XmlElementDecl, then it is an error. 如果类型未使用XmlElementDecl进行批注,那么这是一个错误。

If type() is not JAXBElement.class, then this value must be "". 如果type()不是JAXBElement.class,则此值必须为“”。

By the way 顺便说说

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

does not seem valid to me. 对我来说似乎没有用。 @XmlElementRef are not supposed to map properties of the target class. @XmlElementRef不应映射目标类的属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM