简体   繁体   English

JAXB XMLAdapter编组的问题

[英]Issue with JAXB XMLAdapter marshalling

I have a requirement to generate an XML file with below format using JAXB2 , It has both Fixed and Variable xml content. 我需要使用JAXB2生成以下格式的XML文件,它具有固定可变 xml内容。

What is the Constraint? 什么是约束?

The content of Variable XML Part should be one of the 5 different XML schema ( planned to have JAXB2.0 implemented 5 different java classes to generate it) which is need to be embedded in the fixed XML content. 可变XML部分的内容应该是5种不同的XML schema (计划让JAXB2.0实现5种不同的Java类来生成它),该模式需要嵌入固定的XML内容中。

XML Format: XML格式:

<user_info>
  <header>     //Fixed XML Part
     <msg_id>..</msg_id>
     <type>...</type>
  </header>
  <user_type>    //  Variable XML content
                      // (userType : admin, reviewer, auditer, enduser, reporter)
    ........  
  </user_type>
</user_info>

What I tried ? 我尝试了什么?

I have created a JAXB annotated Java classes for the above XML metadata . 我已经为上述XML metadata创建了一个带有JAXB注释的Java类。 For the variable XML part, I used common Parent class ( BaseUserType ) which was extended by all 5 different Classes <user_type> . 对于可变XML部分,我使用了公共的Parent类( BaseUserType ),该类被所有5个不同的类<user_type>扩展。 And tried to Override the marshall(..) operation using @XmlJavaTypeAdapter . 并尝试使用@XmlJavaTypeAdapter覆盖marshall(..)操作。 (as below) (如下)

JAXB Annotated Class: JAXB注释的类:

@XmlRootElement(name="user_info")
public class UserInfo {

    private Header header;  //reference to JAXB annotated Class Header.class

    @XmlJavaTypeAdapter(value=CustomXMLAdapter.class)
    private BaseUserType userType; // Base class - acts as a common Type
                                    //  for all 5 different UserType JAXB annotated Classes

    // Getters setters here..
    // Also tried to declare JAXB annotations at Getter method
}

Custom XML Adapter Class: 自定义XML适配器类:

public class CustomXMLAdapter extends XmlAdapter<Writer, BaseInfo> { 
       private Marshaller marshaller=null; 

        @Override 
        public BaseInfo unmarshal(Writer v) throws Exception { 
            // Some Implementations here...
        }

        @Override 
        public Writer marshal(BaseInfo v) throws Exception { 
                OutputStream outStream = new ByteArrayOutputStream(); 
                Writer strResult = new OutputStreamWriter(outStream); 
                if(v instanceof CustomerProfileRequest){ 
                    getMarshaller().marshal((CustomerProfileRequest)v, strResult ); 
                } 
                return strResult; 
        }

        private Marshaller getMarshaller() throws JAXBException{ 
                if(marshaller==null){ 
                        JAXBContext jaxbContext = JAXBContext.newInstance(Admin.class, Reviewer.class, Enduser.class, Auditor.class, Reporter.class);
                        marshaller = jaxbContext.createMarshaller(); 
                } 
                return marshaller; 
        } 
}

Where I'm Struggling now?. 我现在在哪里挣扎?

I'm not facing any errors or warnings, the XML is being generated (as shown below). 我没有遇到任何错误或警告,正在生成XML (如下所示)。 But the output is not the expected one. 但是输出不是预期的。 It doesn't embeds the Variable XML part with Fixed one correctly . 没有正确地将Variable XML部分嵌入带有Fixed 1的部分

Output 产量

 <user_info>
        <header> 
           <msg_id>100</msg_id>
           <type>Static</type>
        </header>
        <user_type/> // Empty Element, even though we binded the value properly.
    </user_info>

My Questions are : 我的问题是:

  1. Why the JAXB marshallers could not embeds the " CustomXMLAdapter " marshalled content with Parent one (UserInfo.class) . 为什么JAXB marshallers无法将“ CustomXMLAdapter ”编组的内容与父级1 (UserInfo.class)嵌入。
  2. Do we have an any alternative option in JAXB to do this Simple? 我们在JAXB是否有其他选择可以做到这一点?
  3. How to specify the BoundType , ValueType in XMLAdapter . 如何指定BoundTypeValueTypeXMLAdapter Is there any specific Type to be given in order to Embed the content to Parent Class Marshalling? 为了将内容嵌入到父类编组中,是否需要指定任何特定类型?

An XmlAdapter works by allowing you to convert from your domain object, to another value object that JAXB can better handle for the purposes of Marshalling/Unmarshalling. 通过允许您从域对象转换为JAXB可以更好地处理编组/解组目的的另一个值对象, XmlAdapter起作用。

If all the model objects from the other schemas are really sub classes of BaseUserType , then all you need to do is make the JAXBContext aware of them. 如果其他模式中的所有模型对象实际上都是BaseUserType子类,那么您需要做的就是让JAXBContext意识到它们。 You can do this when you create the JAXBContext by having a colon separated String with all the package names. 在创建JAXBContext时,可以通过用冒号分隔所有包名称的String来完成此操作。

JAXBContext jc = JAXBContext.newInstance("com.example.common:com.example.foo:com.example.bar");

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

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