我正在从WSDL创建一个Web服务客户端。
对服务的典型SOAP请求如下所示:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:someGateway">
<soapenv:Header/>
<soapenv:Body>
<urn:send>
<urn:message>
<urn:messageID>1001</urn:messageID>
<urn:messageBody>
<DataContainer>
SOME MORE ELEMENTS
</DataContainer>
</urn:messageBody>
</urn:message>
</urn:send>
</soapenv:Body>
</soapenv:Envelope>
我使用JAX-WS生成服务工件,并按如下所示填充我的对象:
Message message = objectFactory.createMessage();
//Set message ID
String messageID = "123456"
message.setMessageID(messageID );
//Set message Body
MessageBody messageBody = objectFactory.createMessageMessageBody()
messageBody对象只有1个方法messageBody.setAny(value)。但是我需要在其中放置一个DataContainer元素。
我尝试过:
org.w3c.dom.DocumentObject(我得到“ javax.xml.ws.soap.SOAPFaultException:无法处理该请求。”)可能是由于xml分离。
由XX的JAXB生成的DataContainer对象(我得到了“ [[javax.xml.bind.JAXBException:类DataContainer或其任何超类对此上下文是已知的]]”)
JAXBElement(我得到了“ [[javax.xml.bind.JAXBException:此上下文不知道类DataContainer]”))
我究竟做错了什么?或者我需要怎么做才能在消息正文中获取DataContainer
最佳答案
如前所述,您有messageBody.setAny(value)
,这意味着MessageBody的XSI:type
已设置为anytype
。这意味着您可以在那里设置任何对象,作为JAXB的对象应该能够在JAX-WS wsdl2java工具定义的上下文中封送它。从错误消息“在Conext中找不到DataContainer”看来,您的DataContainer类不在同一上下文中。
这是一种解决方法,您可以将DataContainer对象编组为JAXBElement<String>
(或者可能只是一个String,但我不确定是否可以使用)对象,然后将其设置为anyType。这样一来,您就不会在上下文中知道Class,因为String是基本的JAXB类型。
当您尝试使用第2点或第3点时,我不知道您是如何定义包结构的,所以我在这里采取了疯狂的措施。根据错误消息,看来您单独生成的DataContainer类与Message及其子类不在同一个程序包中。尝试将DataContainer及其关联的类移动到与Message Class相同的包中,并将两个ObjectFactory类合并在一起。这应该允许JAXB在与Message相同的“上下文”中找到DataContainer。
当您发出实际的请求并且JAXB正在编组对象以创建请求时(即JAX-WS在内部调用JAXB Marshelling服务),可能会发生错误。在这种情况下,当您生成客户端时,JAXBContext被设置为Message类所在的包。
这是一个简单的教程,涉及JAXBContext封送处理和取消封送处理。
http://download.oracle.com/docs/cd/E17802_01/webservices/webservices/docs/1.6/tutorial/doc/JAXBUsing3.html
同样按照this,您可能可以将anyType设置为org.w3c.dom.Element而不是org.w3c.dom.Document