输出JAXB带注释的bean属性和suppress元素标记

时间:2012-06-01 04:13:53

标签: java jaxb

我目前有以下两个POJO课程。

@XmlRootElement(name = "user")
@XmlAccessorType(XmlAccessType.FIELD)
public class User {
    @XmlElement
    private String firstName;
    @XmlElement
    private String lastName;
    @XmlElement
    private String email;

    /* snipped getters, setters, and constructors. */
}


@XmlRootElement(name = "testobj")
@XmlAccessorType(XmlAccessType.FIELD)
public class TestObj {
    @XmlElement(name="data")
    private String someData;
    @XmlElement
    private User user;

    /* snipped getters, setters, and constructors. */
}

当前输出

<testObj>
    <name>testObj</name>
    <user>
        <firstName>John</firstName>
        <lastName>Doe</lastName>
        <email>john@doe.org</email>
    </user>
</testObj>

所需输出

<testObj>
    <data>some data</data>
    <firstName>John</firstName>
    <lastName>Doe</lastName>
    <email>john@doe.org</email>
</testObj>

有什么办法可以达到预期的输出效果吗? 嵌套用户对象的基本原理是有类型的heirarchies,如:

User
  |-> Customer
        |-> SpecialCustomer

DetailedUser
  |-> DetailedCustomer
        |-> DetailedSpecialCustomer

这六种类型专门用于保存将作为API调用的结果输出的数据。他们没有逻辑。应用程序在内部使用另一组更复杂的类型,以及一组将内部应用程序类型转换为api输出类型的工厂。 使用JAXB和Jackson将API输出类型序列化为XML和JSON。 为了避免重复的代码,我想使用组合将简单的User | Customer | SpecialCustomer嵌入到复杂类型中,如下所示:

@XmlRootElement(name = "user")
@XmlAccessorType(XmlAccessType.FIELD)
public class DetailedUser {
    @Xml[...?]
    private User user;
    @XmlElement
    private String otherProperty;
    @XmlElement
    private String extraStuff;

    /* snipped getters, setters, and constructors. */
}

当通过JAXB输出DetailedUser时,它应该是这样的:

<user>
    <firstName>John</firstName>
    <lastName>Doe</lastName>
    <email>john@doe.org</email>
    <otherProperty>something</otherProperty>
    <extraStuff></extraStuff>
</user>

对象树将通过Spring MVC以适当的格式使用内容协商输出。

1 个答案:

答案 0 :(得分:2)

注意:我是EclipseLink JAXB (MOXy)主管,是JAXB 2 (JSR-222)专家组的成员。

您可以使用MOXy的@XmlPath(".")扩展程序:

<强> TestObj

package forum10844319;

import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlRootElement(name = "testobj")
@XmlAccessorType(XmlAccessType.FIELD)
public class TestObj {
    @XmlElement(name="data")
    private String someData;
    @XmlPath(".")
    private User user;

    /* snipped getters, setters, and constructors. */
}

用户

package forum10844319;

import javax.xml.bind.annotation.*;

@XmlRootElement(name = "user")
@XmlAccessorType(XmlAccessType.FIELD)
public class User {
    @XmlElement
    private String firstName;
    @XmlElement
    private String lastName;
    @XmlElement
    private String email;

    /* snipped getters, setters, and constructors. */
}

<强> jaxb.properties

要将MOXy指定为JAXB提供程序,您需要在与域模型相同的包中包含名为jaxb.properties的文件:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

<强>演示

package forum10844319;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

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

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum10844319/input.xml");
        TestObj testObj = (TestObj) unmarshaller.unmarshal(xml);

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

}

<强> input.xml中/输出

<testobj>
    <data>some data</data>
    <firstName>John</firstName>
    <lastName>Doe</lastName>
    <email>john@doe.org</email>
</testobj>