首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JAXB封送多态POJO到XML

JAXB封送多态POJO到XML
EN

Stack Overflow用户
提问于 2018-10-04 05:08:51
回答 1查看 116关注 0票数 2

我试图使用JAXB来封送类文件(带有注释)。在<profile-set>下,它可以有不同的标签。

代码语言:javascript
复制
<organization-information-profile>
<connection-profile>
<user-information-profile>

示例输出XML文件如下所示

a)

代码语言:javascript
复制
    <?xml version="1.0"?>
    <request version="2.0" principal="111" credentials="xxxxx">
      <target name="TestAPI" operation="create">
        <parameter>
          <organization>
            <qualified-name>some-qualified-name</qualified-name>
            <profile-set>
              <name>TestOrg</name>
              <organization-information-profile>
                <name>Organization Information</name>
                <qualified-name>/Organization Information</qualified-name>
                <last-name>Test</last-name>
                <address>some-address</address>
                <city>my-city</city>
                <province></province>
                <postal-code>1111</postal-code>
                <country>Timbaktu</country>
                <phone-number-day>1111</phone-number-day>
                <email-address>some@email.com</email-address>
                <attribute name="PhoneNumber1">
                  <value context="organization">23333</value>
                </attribute>
                <attribute name="ShortName">
                  <value context="organization">my company</value>
                </attribute>
                <attribute name="TaxId">
                  <value context="organization">myorg</value>
                </attribute>
              </organization-information-profile>
            </profile-set>
          </organization>
        </parameter>
      </target>
</request>

b)

代码语言:javascript
复制
        <?xml version="1.0"?>
        <request version="2.0" principal="11111" credentials="xxxxx">
          <target name="TestAPI" operation="update">
            <parameter>
              <organization>
                <qualified-name>some-qualified-name</qualified-name>
                <profile-set>
                  <name>TestOrg</name>
                  <connection-profile>
                    <qualified-name>some-qualified-name</qualified-name> 
                    <service>
                      <name>some service</name> 
                    </service>
                    <attribute name="att-1">
                      <value context="organization" segment="some-segment" subscript="524288">fill-the-value</value> 
                    </attribute>
                    <attribute name="att-2">
                      <value context="organization" segment="some-segment" subscript="524288">qedqwe</value> 
                    </attribute>            
                  </connection-profile>
                </profile-set>
              </organization>
            </parameter>
          </target>
        </request> 

下面是代码(只有配置文件集)

代码语言:javascript
复制
 public static class ProfileSet
    {
        @XmlElement(name = "name")
        public String name;

        // innerPayLoad is template to store different profile objects
        @XmlJavaTypeAdapter(CustomAdaptor.class)
        @XmlElement
        public InnerPayLoad innerPayLoad;

        public ProfileSet(String name, InnerPayLoad innerPayLoad)
        {
            this.name = name;
            this.innerPayLoad = innerPayLoad;
        }

    }

和CustomAdaptor

代码语言:javascript
复制
public class CustomAdaptor extends XmlAdapter<String,InnerPayLoad<?>>
{


    @Override
    public InnerPayLoad<?> unmarshal(String v) throws Exception
    {
        return null;
    }

    @Override
    public String marshal(InnerPayLoad<?> v) throws Exception
    {
         String value = TestCode.convertToXmlNoHeader(v.whichProfile,v.whichProfile.getClass());

         // after converting value becomes 

        //  <organization-information-profile>
        //      <name>Organization Information</name>
        //  </organization-information-profile> 

        return value;
    }
}       

但最终生成的XML与organization-information-profile的(a)不同。

代码语言:javascript
复制
 <?xml version='1.0' encoding='UTF-8'?>
<request version="2.0" principle="11111" credentials="xxxxx">
  <target name="TestAPI" operation="create">
    <parameter>
      <organization>
        <qualified-name>newOrg</qualified-name>
        <profile-set>
          <innerPayLoad>&lt;organization-information-profile>
    &lt;name>Organization Information&lt;/name>
&lt;/organization-information-profile></innerPayLoad>
          <name>testOrg</name>
        </profile-set>
      </organization>
    </parameter>
  </target>
</request>

是否可以删除<innerPayLoad>标记,只使用CustomAdaptor封送函数返回值进行插入?

感谢解决这个问题的帮助和提示。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-04 10:25:16

您不需要为ProfileSet中的各种配置文件类型编写自定义适配器。

相反,为了处理这种混合XML内容,规范方法如下所示。

在您的ProfileSet类中,您应该定义一个多态profile属性,它可以接受<organization.information-profile><connection-profile><user-information-profile>元素的内容。(我更喜欢这里的名称profile,而不是innerPayload)。这些XML元素名称和Java类之间的映射是通过使用@XmlElements注释完成的。

代码语言:javascript
复制
@XmlAccessorType(XmlAccessType.FIELD)
public class ProfileSet {

    @XmlElement(name = "name")
    private String name;

    // template to store different profile objects    
    @XmlElements({
        @XmlElement(name = "organization-information-profile", type = OrganizationInfomationProfile.class),
        @XmlElement(name = "connection-profile", type = ConnectionProfile.class),
        @XmlElement(name = "user-information-profile", type = UserInformationProfile.class)
    })
    private Profile profile;

    // default constructor used by JAXB unmarshaller
    public ProfileSet() {
    }

    public ProfileSet(String name, Profile profile) {
        this.name = name;
        this.profile = profile;
    }
 }

您需要一个抽象的超类Profile,它只包含所有类型配置文件所共有的属性:

代码语言:javascript
复制
@XmlAccessorType(XmlAccessType.FIELD)
public abstract class Profile {

    @XmlElement
    private String name;

    @XmlElement(name = "attribute")
    private List<Attribute> attributes;
}

有一个子类OrganizationInformationProfile来表示<organization-information-profile>元素。

代码语言:javascript
复制
@XmlAccessorType(XmlAccessType.FIELD)
public class OrganizationInfomationProfile extends Profile {

    @XmlElement(name = "qualified-name")
    private String qualifiedName;

    @XmlElement(name = "last-name")
    private String lastName;

    @XmlElement(name = "address")
    private String address;

    // ... other properties

}

和另一个子类ConnectionProfile,用于表示<connection-profile>元素。

代码语言:javascript
复制
@XmlAccessorType(XmlAccessType.FIELD)
public class ConnectionProfile extends Profile {

    @XmlElement(name = "service")
    private Service service;
}

还有另一个子类UserInformationProfile,用于表示<user-information-profile>元素。

通过使用上述方法,您可以解组XML示例,并在编组时再次获得相同的输出。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52639400

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档