2013-04-25 36 views
2

我的問題是我有一個類類型MessageList中,它包含消息的物品,定義爲這樣的:編組類放入XSD:ANYTYPE XML

<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"/> 

我的消息類看起來像(具有getter和setter我「這裏已經離開了)

public class Message 
{ 
private String referenceId; 
private String messageType; 
private Timestamp createdTime; 
private String transactionIdForeignKey; 
private String xmlDetail; 
} 

當我嘗試元帥這個類我的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); 
     } 

我收到以下錯誤:

[#|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) 

任何人都知道爲什麼會發生這種情況?我猜測正在進行編組的servlet需要知道要查看哪個類,但我不知道如何執行此操作?

+0

@ bmorris591已經有了比我提供的更徹底的答案,所以我只是評論。缺點是xmlAnyElement僅用於解組。這只是JAXB類沒有的其他XML中的元素的全部。你不能用它來編組JAXB類的所有其他屬性。 http://docs.oracle.com/javaee/5/api/javax/xml/bind/annotation/XmlAnyElement。html – 2013-04-25 17:36:45

回答

5

如果你想在課堂上做到精確,你需要在模式中更加精確。

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; 
    } 

} 

你可以看到,所有的JAXB可以從您的模式講的是你有一個MessageType類,它包含的東西未知量 - <xsd:any/> - 有沒有辦法讓JAXB例如,確定您有一個String,這個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> 

告訴JAXB它需要建立在類的信息(TimeStamp是在這種情況下long - 來解讀你需要一些custom logic一個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; 
    } 

} 

你可以看到,直接在類中的字段屬性的XML映射。您還可以看到JAXB使用的註釋,這些註釋是not required,但有助於告訴它如何映射到哪裏。

如果你不能改變你的模式,那麼你將需要實現自定義邏輯來搜索你的<xsd:any/>的相關屬性和映射,然後手動。如果沿着這條路線走下去,This應該讓你開始。

+0

謝謝,我很懷疑這是答案,將不得不返回到繪圖板! – user898465 2013-04-26 06:05:45