use*_*465 2 java xsd jax-ws marshalling
我的问题是我有一个MessageList类,它包含Message项,定义如下:
<xsd:complexType name="MessageType">
<xsd:sequence>
<xsd:any/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="Message" type="tns:MessageType"/>
<xsd:complexType name="MessageListType">
<xsd:sequence>
<xsd:element name="Message" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="MessageList" type="tns:MessageListType"/>
Run Code Online (Sandbox Code Playgroud)
我的消息类看起来像(我在这里省略了getter和setter)
public class Message
{
private String referenceId;
private String messageType;
private Timestamp createdTime;
private String transactionIdForeignKey;
private String xmlDetail;
}
Run Code Online (Sandbox Code Playgroud)
当我尝试在我的servlet中封送这个类时,如:
List<Message> retrievedMessages = new ArrayList<Message>();
retrievedMessages.add(new Message);
retrievedMessages.add(new Message);
MessageListType messageListType = new MessageListType();
for(Message message: retrievedMessages){
messageListType.getMessage().add(message);
}
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
[#|2013-04-25T16:43:40.434+0100|WARNING|sun-appserver2.1|javax.enterprise.system.stream.err|_ThreadID=188;_ThreadName=p: thread-pool-1; w: 76;_RequestID=40c6fe10-c12f-4d0b-8912-c960381910d7;|
javax.xml.ws.WebServiceException: javax.xml.bind.MarshalException
- with linked exception:
[javax.xml.bind.JAXBException: class uk.co.test.test.audit.model.Message nor any of its super class is known to this context.]
at com.sun.xml.ws.message.jaxb.JAXBMessage.writePayloadTo(JAXBMessage.java:322)
at com.sun.enterprise.jbi.serviceengine.comm.WrappedMessage.writePayloadTo(WrappedMessage.java:419)
at com.sun.enterprise.jbi.serviceengine.comm.WrappedMessage$DocumentStyleWrapper.wrap(WrappedMessage.java:215)
at com.sun.enterprise.jbi.serviceengine.comm.WrappedMessage.wrap(WrappedMessage.java:170)
at com.sun.enterprise.jbi.serviceengine.comm.ProviderInOut.send(ProviderInOut.java:143)
at com.sun.enterprise.jbi.serviceengine.bridge.transport.NMRServerConnection.sendResponse(NMRServerConnection.java:81)
at com.sun.enterprise.jbi.serviceengine.bridge.transport.JBIAdapter$WSToolkit.handle(JBIAdapter.java:127)
at com.sun.enterprise.jbi.serviceengine.bridge.transport.JBIAdapter.handle(JBIAdapter.java:86)
at com.sun.enterprise.jbi.serviceengine.bridge.JAXWSMessageProcessor.doWork(JAXWSMessageProcessor.java:93)
at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:555)
Caused by: javax.xml.bind.MarshalException
- with linked exception:
[javax.xml.bind.JAXBException: class uk.co.test.test.audit.model.Message nor any of its super class is known to this context.]
at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:282)
at com.sun.xml.bind.v2.runtime.BridgeImpl.marshal(BridgeImpl.java:100)
at com.sun.xml.bind.api.Bridge.marshal(Bridge.java:141)
at com.sun.xml.ws.message.jaxb.JAXBMessage.writePayloadTo(JAXBMessage.java:315)
Run Code Online (Sandbox Code Playgroud)
任何人都知道为什么会这样吗?我猜测正在进行编组操作的servlet需要知道要查看哪个类,但我不知道该怎么做?
如果您希望在课堂上保持精确,则需要在Schema中更精确.
JAXB依赖于定义结构的模式,该结构与您希望JAXB解组的结构相同.
为了说明,让我们使用xjc- 编译您的模式- 这将创建JAXB可以自动编写的类并对其进行注释.
这是班级:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "MessageType", propOrder = {
"any"
})
public class MessageType {
@XmlAnyElement(lax = true)
protected Object any;
public Object getAny() {
return any;
}
public void setAny(Object value) {
this.any = value;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以看到,所有JAXB都可以从您的模式中判断出您有一个MessageType包含未知数量的东西的类 - <xsd:any/>例如,JAXB无法确定您是否需要设置一个String被调用的东西referenceId.
如果您可以更改架构,则更新为
<xsd:complexType name="MessageType">
<xsd:attribute name="referenceId" type="xsd:string"/>
<xsd:attribute name="messageType" type="xsd:string"/>
<xsd:attribute name="transactionIdForeignKey" type="xsd:string"/>
<xsd:attribute name="xmlDetail" type="xsd:string"/>
<xsd:attribute name="createdTime" type="xsd:integer"/>
</xsd:complexType>
Run Code Online (Sandbox Code Playgroud)
告诉JAXB它需要建立在类(信息TimeStamp是long在这种情况下-解组到TimeStamp你需要一些自定义逻辑).
生成的类现在类似于您自己的类:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "MessageType")
public class MessageType {
@XmlAttribute(name = "referenceId")
protected String referenceId;
@XmlAttribute(name = "messageType")
protected String messageType;
@XmlAttribute(name = "transactionIdForeignKey")
protected String transactionIdForeignKey;
@XmlAttribute(name = "xmlDetail")
protected String xmlDetail;
@XmlAttribute(name = "createdTime")
protected BigInteger createdTime;
public String getReferenceId() {
return referenceId;
}
public void setReferenceId(String value) {
this.referenceId = value;
}
public String getMessageType() {
return messageType;
}
public void setMessageType(String value) {
this.messageType = value;
}
public String getTransactionIdForeignKey() {
return transactionIdForeignKey;
}
public void setTransactionIdForeignKey(String value) {
this.transactionIdForeignKey = value;
}
public String getXmlDetail() {
return xmlDetail;
}
public void setXmlDetail(String value) {
this.xmlDetail = value;
}
public BigInteger getCreatedTime() {
return createdTime;
}
public void setCreatedTime(BigInteger value) {
this.createdTime = value;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以看到xml中的属性直接映射到类中的字段.您还可以看到JAXB使用的注释,这些注释不是必需的,但有助于告诉它要映射到哪里.
如果您无法更改架构,则需要实现自定义逻辑以搜索<xsd:any/>相关属性并手动映射.如果沿着这条路走下去,这应该可以让你开始.
| 归档时间: |
|
| 查看次数: |
5557 次 |
| 最近记录: |