Marshal SOAP body包含扩展org.xmlsoap.schemas.soap.encoding.Array的元素

时间:2014-10-22 12:52:51

标签: java xml web-services soap jaxb

我正在尝试编组扩展 org.xmlsoap.schemas.soap.encoding.Array 的对象。 JAXB编译器生成了以下类:public class ParameterValueList extends Array

除其他事项外,

ParameterValueList包含(或应该)ParameterValueStruct个对象。

为了进行测试,我尝试以下代码:

Send send = new Send();
send.setMaxEnvelopes(5);
send.setCurrentTime(new XMLGregorianCalendarImpl(new GregorianCalendar(1980, 03, 04)));

    DeviceIdStruct devIDStruct = new DeviceIdStruct();
    devIDStruct.setOUI("oui");
    devIDStruct.setManufacturer("manu");
    devIDStruct.setProductClass("pclass");
    devIDStruct.setSerialNumber("123456");

send.setDeviceId(devIDStruct);

        ParameterValueStruct pvs = new ParameterValueStruct();
        pvs.setName("pvs_name");
        pvs.setValue(new Integer(5));
        ParameterValueStruct pvs2 = new ParameterValueStruct();
        pvs2.setName("pvs2_name");
        pvs2.setValue(new Integer(52));

    ParameterValueList pvl = new ParameterValueList();
    pvl.getAny().add(pvs);
    pvl.getAny().add(pvs2);

send.setParameterList(pvl);

try {

    File file = new File("C:\\file.xml");
    JAXBContext jaxbContext = JAXBContext.newInstance(Send.class);
    Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

    // output pretty printed
    jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

    jaxbMarshaller.marshal(send, file);
    jaxbMarshaller.marshal(send, System.out);

} catch (JAXBException e) {
  e.printStackTrace();
}

程序编译正常但我尝试运行它时得到的异常如下:

javax.xml.bind.MarshalException
 - with linked exception:
[com.sun.istack.internal.SAXException2: class org.me.custom_3_1.ParameterValueStruct nor any of its super class is known to this context.
javax.xml.bind.JAXBException: class org.me.custom_3_1.ParameterValueStruct nor any of its super class is known to this context.]
    at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:311)
    at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:236)
    at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:103)
    at test.TestUnmarshal.main(TestUnmarshal.java:55)
Caused by: com.sun.istack.internal.SAXException2: class org.me.custom_3_1.ParameterValueStruct nor any of its super class is known to this context.
javax.xml.bind.JAXBException: class org.me.custom_3_1.ParameterValueStruct nor any of its super class is known to this context.
    at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:235)
    at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:250)
    at com.sun.xml.internal.bind.v2.runtime.property.ArrayReferenceNodeProperty.serializeListBody(ArrayReferenceNodeProperty.java:107)
    at com.sun.xml.internal.bind.v2.runtime.property.ArrayERProperty.serializeBody(ArrayERProperty.java:144)
    at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:343)
    at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:335)
    at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:685)
    at com.sun.xml.internal.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:143)
    at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:343)
    at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsSoleContent(XMLSerializer.java:582)
    at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:325)
    at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:483)
    at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:308)
    ... 3 more

我还附加了用于生成JAXB类的xsd文件 Netbeans 8

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:tns="urn:me-org:custom-3-1"
    targetNamespace="urn:me-org:custom-3-1"
    elementFormDefault="unqualified"
    attributeFormDefault="unqualified">

    <xs:import namespace="http://schemas.xmlsoap.org/soap/envelope/"
        schemaLocation="http://schemas.xmlsoap.org/soap/envelope/"/>
    <xs:import namespace="http://schemas.xmlsoap.org/soap/encoding/"
        schemaLocation="http://schemas.xmlsoap.org/soap/encoding/"/>


    <!--    SOAP Header Elements -->  
    <xs:element name="ID">
        <xs:complexType>
            <xs:simpleContent>
                <xs:extension base="xs:string">
                    <xs:attribute ref="soapenv:mustUnderstand" use="required" fixed="1"/>
                </xs:extension>
            </xs:simpleContent>
        </xs:complexType>
    </xs:element>

    <xs:element name="HoldRequests">
        <xs:complexType>
            <xs:simpleContent>
                <xs:extension base="xs:boolean">
                    <xs:attribute ref="soapenv:mustUnderstand" use="required" fixed="1"/>
                </xs:extension>
            </xs:simpleContent>
        </xs:complexType>
    </xs:element>  

    <!-- Type definitions -->    
    <xs:complexType name="DeviceIdStruct">
        <xs:sequence>
            <xs:element name="Manufacturer">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:maxLength value="64"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>
            <xs:element name="OUI">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:length value="6"/>
                        <xs:pattern value="[0-9A-F]{6}"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>
            <xs:element name="ProductClass">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:maxLength value="64"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>
            <xs:element name="SerialNumber">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:maxLength value="64"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>


    <xs:complexType name="ParameterValueStruct">
        <xs:sequence>
            <xs:element name="Name">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:maxLength value="256"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>
            <xs:element name="Value" type="xs:anySimpleType"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="ParameterValueList">
        <xs:complexContent>
            <xs:restriction base="soapenc:Array">
                <xs:sequence>
                    <xs:element name="ParameterValueStruct" type="tns:ParameterValueStruct" minOccurs="0" maxOccurs="unbounded"/>
                </xs:sequence>
                <xs:attribute ref="soapenc:arrayType" use="required"/>
            </xs:restriction>
        </xs:complexContent>
    </xs:complexType>

    <xs:simpleType name="CommandKeyType">
        <xs:restriction base="xs:string">
            <xs:maxLength value="32"/>
        </xs:restriction>
    </xs:simpleType>

    <!--   messages  -->

    <!-- Send -->
    <xs:element name="Send">
        <xs:annotation>
            <xs:documentation>SendMessage </xs:documentation>
        </xs:annotation>
        <xs:complexType>
            <xs:sequence>
                <xs:element name="DeviceId" type="tns:DeviceIdStruct"/>                
                <xs:element name="MaxEnvelopes" type="xs:unsignedInt"/>
                <xs:element name="CurrentTime" type="xs:dateTime"/>                
                <xs:element name="ParameterList" type="tns:ParameterValueList"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <!-- MessageResponse -->
    <xs:element name="MessageResponse">
        <xs:annotation>
            <xs:documentation>MessageResponse</xs:documentation>
        </xs:annotation>
        <xs:complexType>
            <xs:sequence>
                <xs:element name="MaxEnvelopes" type="xs:unsignedInt"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

</xs:schema>

UPDATE - 添加生成的ParameterValueList

package org.me.custom_3_1;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
import org.xmlsoap.schemas.soap.encoding.Array;


/**
 * <p>Java class for ParameterValueList complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType name="ParameterValueList">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://schemas.xmlsoap.org/soap/encoding/}Array">
 *       &lt;sequence>
 *         &lt;element name="ParameterValueStruct" type="{urn:me-org:custom-3-1}ParameterValueStruct" maxOccurs="unbounded" minOccurs="0"/>
 *       &lt;/sequence>
 *       &lt;attribute ref="{http://schemas.xmlsoap.org/soap/encoding/}arrayType use="required""/>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ParameterValueList")
public class ParameterValueList
    extends Array
{


}

更新#2--基于@Victor的评论

我在@XmlSeeAlso(ParameterValueStruct.class)的类声明和ParameterValueList ParameterValueStruct`中添加了@XmlRootElement(name = "ParameterValueStruct") at注释。

--- 输出

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns3:Send xmlns:ns2="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns3="urn:me-org:custom-3-1">
    <DeviceId>
        <Manufacturer>manu</Manufacturer>
        <OUI>oui</OUI>
        <ProductClass>pclass</ProductClass>
        <SerialNumber>123456</SerialNumber>
    </DeviceId>
    <MaxEnvelopes>5</MaxEnvelopes>
    <CurrentTime>1980-04-04T00:00:00.000+03:00</CurrentTime>
    <ParameterList>
        <ns3:ParameterValueStruct>
            <Name>pvs_name</Name>
            <Value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">5</Value>
        </ns3:ParameterValueStruct>
        <ns3:ParameterValueStruct>
            <Name>pvs2_name</Name>
            <Value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">52</Value>
        </ns3:ParameterValueStruct>
    </ParameterList>
</ns3:Send>

所以它似乎有用,但有两件事我不喜欢。

1 - 我是否应该首先篡改自动生成的课程?

2 - JAXB将输出与通用名称空间一起编组,例如:<Value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">5</Value>。这似乎是预期的,因为在ParameterValueStruct中有一个对象字段:受保护的对象值;我在这里找到了:How to get rid of namespace when marshaling generic objects with JAXB类似的问题。

0 个答案:

没有答案