繁体   English   中英

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

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

我有以下物品

电影

@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<? extends Person> JAXBElement<? extends Person>而不是Person

问题是,@ XmlElementRef.name不适用于@XmlRootElement ,请在此处阅读:

如果type()是JAXBElement.class,则namespace()和name()指向带有XmlElementDecl的工厂方法。 XML元素名称是工厂方法的XmlElementDecl批注中的元素名称,或者如果在XML文档中替换了其替换组中的元素(其为head元素),则元素名称来自替换的XmlElementDecl元件。

如果type()不是JAXBElement.class,则XML元素名称是使用类型上的注释XmlRootElement与类型静态关联的XML元素名称。 如果类型未使用XmlElementDecl进行批注,那么这是一个错误。

如果type()不是JAXBElement.class,则此值必须为“”。

顺便说说

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

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

暂无
暂无

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

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