我正在从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对象只有一个方法messageBody.setAny(value)。但我需要在其中放置一个DataContainer元素。
我试过传递:
我做错了什么?或者我需要做什么才能在邮件正文中获取DataContainer
答案 0 :(得分:1)
如前所述,您有messageBody.setAny(value)
,这意味着MessageBody的XSI:type
已设置为anytype
。这意味着您可以在那里设置任何对象,JAXB应该能够在JAX-WS wsdl2java工具定义的上下文中封送它。从错误消息'无法在Conext中找到DataContainer'看来,您的DataContainer类似乎不在同一个上下文中。
这是一个解决方法,您可以将DataContainer对象编组为JAXBElement<String>
(或者可能只是一个字符串,但我不确定它是否可行)对象然后将其设置为anyType。这样你就不会在上下文中得到Class,因为String是一个基本的JAXB类型。
当你尝试使用第2点或第3点时,我不知道你是如何定义你的包结构的,所以我在这里采取狂野的刺。从错误消息中,您似乎单独生成的DataContainer类与Message及其子类不在同一个包中。尝试将DataContainer及其关联的类移动到与Message Class相同的包中,并将两个ObjectFactory类合并在一起。这应该允许JAXB在与Message相同的“上下文”中找到DataContainer。
当您发出实际请求并且JAXB正在编组对象以创建请求时(即JAX-WS在内部调用JAXB Marshelling服务),可能会发生错误。在这种情况下,当您生成客户端时,JAXBContext被设置为Message类所在的包。
这是一个处理JAXBContext Marshaling和unmarshaling的简单教程。 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
答案 1 :(得分:0)
使用xs的秘诀:任何未包含的XSD类型都是@XmlSeeAlso
。从xjc工具创建JAXB类时,您将获得一个定义@WebService
方法的接口。该接口也将由客户端和服务实现使用。如果您不想修改自动生成的java文件,最好在包中扩展此界面,并将@XmlSeeAlso({ExternalClassYouWantToReferTo.class})
添加到此新界面,例如:IWebServiceInterface
@WebService(name = "IExternalXmlBatchReceive", targetNamespace = "http://External.ServiceContract.BatchReceive")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
@XmlSeeAlso({
ObjectFactory.class, ExternalClassYouWantToReferTo.class
})
public IWebServiceInterface extends InterfaceYourAutoCreationCode {
@WebMethod(name=...)
......
}
您的所有Service
课程和@WebService
都是通过此界面实现的。
当您的客户调用getPort
方法时,您应该将新实现的接口作为第二个参数传递,如:
IWebServiceInterface wi = service.getPort(YOUR_QNAME, IWebServiceInterface.class);
getPort
方法将查看您为@XmlSeeAlso
传入的接口并初始化其内部JAXBContext。