我正在尝试编组扩展 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>
* <complexType name="ParameterValueList">
* <complexContent>
* <restriction base="{http://schemas.xmlsoap.org/soap/encoding/}Array">
* <sequence>
* <element name="ParameterValueStruct" type="{urn:me-org:custom-3-1}ParameterValueStruct" maxOccurs="unbounded" minOccurs="0"/>
* </sequence>
* <attribute ref="{http://schemas.xmlsoap.org/soap/encoding/}arrayType use="required""/>
* </restriction>
* </complexContent>
* </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类似的问题。