为了账号安全,请及时绑定邮箱和手机立即绑定

没有 @XMLRootElement 的 JAXB 编组和解组子元素

没有 @XMLRootElement 的 JAXB 编组和解组子元素

小怪兽爱吃肉 2022-07-14 16:22:42
我正在尝试编组一个子元素对象以获取 xml 字符串。然后使用这个 xml 字符串我也想解组。为了澄清,我已经从 xsd 生成了我的 jaxb 类,并且我在 ObjectFactory 中没有任何方法可以提供所需的对象。xsd 定义:IBUSStatusType 是根元素 IBUSMessage 的子元素我想编组一个 IBUSStatusType 的对象。为此,我的编组代码如下:  public static StringWriter getStringFromIBUSStatusType(IBUSStatusType iBUSStatusType) throws JAXBException  {    StringWriter stringWriter = new StringWriter();    JAXBContext jaxbContext = JAXBContext        .newInstance(com.myhealth.soa.ibus.v1_1.ObjectFactory.class);    Marshaller marshaller = jaxbContext.createMarshaller();    marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);    marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper",        new DefaultNamespacePrefixMapper());    marshaller.setProperty("com.sun.xml.bind.xmlDeclaration", Boolean.FALSE);    QName qName = new QName("com.myhealth.soa.ibus.v1_1", "iBUSStatusType");    JAXBElement<IBUSStatusType> root = new JAXBElement<>(qName, IBUSStatusType.class, iBUSStatusType);    marshaller.marshal(root, stringWriter);    return stringWriter;  }当我编组 IBUSStatusType 对象时,我得到了这个 xml 字符串:<ns2:iBUSStatusType xmlns:tns="http://soa.myhealth.com/ibus/v1.1.0" xmlns:ns2="com.myhealth.soa.ibus.v1_1"><tns:code>8</tns:code><tns:description>Completed With Warning</tns:description><tns:Messages><tns:Message><tns:Reason><tns:description>Subscriber's email missing</tns:description><tns:code>2187</tns:code></tns:Reason><tns:type>1</tns:type><tns:Context><tns:description>WARN</tns:description>
查看完整描述

2 回答

?
繁星coding

TA贡献1797条经验 获得超4个赞

好吧,最后我们找到了解决方案。我在下面粘贴我的解决方案。我确实根据@Iurii 更改了代码,但问题出在其他地方。


所以,这是编组部分的变化。QName 的第二个参数必须是类名而不是它的对象。我试图按照这个链接https://codenotfound.com/jaxb-marshal-element-missing-xmlrootelement-annotation.html但没有用。当将 QName 的第二个参数更改为类名时,它就起作用了。并且上下文应该由该类构成,因为 ObjectFactory 没有它。


    JAXBContext jaxbContext = JAXBContext.newInstance(IBUSStatusType.class);

    

QName qName = new QName("http://soa.independenthealth.com/ibus/v1.1.0", "IBUSStatusType");

    

JAXBElement<IBUSStatusType> root = new JAXBElement<IBUSStatusType>(qName, IBUSStatusType.class, iBUSStatusType);

    


这是整个 Unmarshal 代码。我们必须在解组之前将 xml 更改为节点。Element的导入是import org.w3c.dom.Element;


  public static IBUSStatusType getIBUSStatusType(String xml)

      throws JAXBException, SAXException, IOException, ParserConfigurationException

  {

    JAXBContext jaxbContext = JAXBContext

        .newInstance(IBUSStatusType.class);

    Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();    

    

    Element node =  DocumentBuilderFactory

        .newInstance()

        .newDocumentBuilder()

        .parse(new ByteArrayInputStream(xml.getBytes()))

        .getDocumentElement();

    

    return ((JAXBElement<IBUSStatusType>) jaxbUnmarshaller.unmarshal(node, IBUSStatusType.class)).getValue();

  }


查看完整回答
反对 回复 2022-07-14
?
Helenr

TA贡献1780条经验 获得超4个赞

看看你的架构


<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://soa.myhealth.com/ibus/v1.1.0" targetNamespace="http://soa.myhealth.com/ibus/v1.1.0" elementFormDefault="qualified">

    <xsd:element name="IBUSMessage" type="tns:IBUSMessage"/>

    <xsd:complexType name="IBUSMessage">

        <xsd:sequence>

            <xsd:element name="Header" type="tns:IBUSHeaderType"/>

            <xsd:element name="Detail" type="tns:IBUSVariantType"/>

            <xsd:element name="Status" type="tns:IBUSStatusType"/>

        </xsd:sequence>

    </xsd:complexType>

有一个命名空间http://soa.myhealth.com/ibus/v1.1.0 ,当您进行解组时,它期望http://soa.myhealth.com/ibus/v1.1.0 但以前当您进行编组时,您放置以下命名空间


QName qName = new QName("com.myhealth.soa.ibus.v1_1", "iBUSStatusType");

它们不一样。


查看完整回答
反对 回复 2022-07-14
  • 2 回答
  • 0 关注
  • 147 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信