上一节讲述了webservice的发布,本节说明一下基于SOAP消息的调用实现细节,按顺序先后
1、创建要访问的ws服务对象
URL endpointURL = new URL("http://localhost:8889/ms?wsdl");//访问的URL
//QName的第一参数是targetNamespace,第二个是name
QName qName= new QName("http://service.soap.org/","MyServiceImplService");
//创建远程服务访问对象
Service service = Service.create(endpointURL, qName);
2、创建消息转发器
//基于消息的方式,因此,后两个参数是SOAPMessage.class, Service.Mode.MESSAGE,第一个参数是要访问的那个服务port的name
Dispatch<SOAPMessage> dispatch = service.createDispatch(new QName("http://service.soap.org/","MyServiceImplPort")/*一定要加上命名空间,否则出错*/,
SOAPMessage.class, Service.Mode.MESSAGE);
3、组建要转发的请求
也就是你要访问那个方法,就组装那个方法的请求(参数),封装到SOAP消息中
SOAPMessage message = MessageFactory.newInstance().createMessage();//创建消息对象,用于获取信封对象
//获取body
SOAPBody body = message.getSOAPPart().getEnvelope().getBody();
//指定具体访问那个方法
QName method = new QName("http://service.soap.org/","addUser","tt");//访问的方法
SOAPElement bodyElement = body.addBodyElement(method);
//父元素写了namespace,子元素就不用写了,namespace具有继承性
SOAPElement user = bodyElement.addChildElement("user");//创建元素,然后添加调用方法的参数内容
user.addChildElement("id").setValue("12");
user.addChildElement("nickname").setValue("tudou123");
user.addChildElement("password").setValue("123123");
user.addChildElement("username").setValue("xxx");
需要说明的是SOAPMessage的是用方法,下面内容是jdk文档中的描述
所有 SOAP 消息的根类。因为 SOAP 消息是通过“导线”传输的,所以它是 XML 文档或第一个正文部分为 XML/SOAP 文档的 MIME 消息。
SOAPMessage 对象由一个 SOAP 部分和一个或多个附件部分(可选)组成。SOAPMessage 对象的 SOAP 部分是一个 SOAPPart 对象,包含了用于消息路由和标识的信息,并可以包含特定于应用程序的内容。消息 SOAP 部分中的所有数据都必须是 XML 格式。
默认情况下,新的 SOAPMessage 对象包含以下对象:
一个 SOAPPart 对象
一个 SOAPEnvelope 对象
一个 SOAPBody 对象
一个 SOAPHeader 对象
可以通过调用方法 SOAPMessage.getSOAPPart() 检索消息的 SOAP 部分。SOAPEnvelope 对象是从 SOAPPart 对象检索的,SOAPEnvelope 对象用于检索 SOAPBody 和 SOAPHeader 对象。
SOAPPart sp = message.getSOAPPart();
SOAPEnvelope se = sp.getEnvelope();
SOAPBody sb = se.getBody();
SOAPHeader sh = se.getHeader();
除强制性 SOAPPart 对象之外,SOAPMessage 对象还可以包含零个或多个 AttachmentPart 对象,每个 AttachmentPart 对象都包含特定于应用程序的数据。SOAPMessage 接口提供了一些用于创建 AttachmentPart 对象的方法,以及一些将它们添加到 SOAPMessage 对象的方法。收到 SOAPMessage 对象的一方可以通过检索各个附件部分来检查消息内容。
与 SOAP 消息的其余部分不同,附件不需要是 XML 格式,因此可以是简单文本或图像文件等任何形式。因此,任何非 XML 格式的消息内容必须在 AttachmentPart 对象中。
MessageFactory 对象可以创建行为特定于具体 SAAJ 实现或应用程序的 SOAPMessage 对象。例如,MessageFactory 对象可以生成符合特定配置文件(如 ebXML)的 SOAPMessage 对象。在这种情况下,MessageFactory 对象可以生成使用 ebXML 头初始化的 SOAPMessage 对象。
4、第3步组装了消息,这里就需要将消息转发给webservice的提供者,并获取响应
SOAPMessage response = dispatch.invoke(message);
很简单,只有一条语句,我们看看返回的内容:
//将结果打印出来
response.writeTo(System.out);
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Header/><S:Body><ns2:addUserResponse xmlns:ns2="http://service.soap.org/"><user><id>12</id><nickname>tudou123</nickname><password>123123</password><username>xxx</username></user></ns2:addUserResponse></S:Body></S:Envelope>
这样,就获取了数据,解析出对象即可。
5、附件(是对应的wsdl文件)
This XML file does not appear to have any style information associated with it. The document tree is shown below. <!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.6 in JDK 6. --> <!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.6 in JDK 6. --> <definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://service.soap.org/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://service.soap.org/" name="MyServiceImplService"> <types> <xsd:schema> <xsd:import namespace="http://service.soap.org/" schemaLocation="http://localhost:8889/testService?xsd=1"/> </xsd:schema> </types> <message name="addUser"> <part name="parameters" element="tns:addUser"/> </message> <message name="addUserResponse"> <part name="parameters" element="tns:addUserResponse"/> </message> <message name="add"> <part name="parameters" element="tns:add"/> </message> <message name="addResponse"> <part name="parameters" element="tns:addResponse"/> </message> <portType name="IMyService"> <operation name="addUser"> <input message="tns:addUser"/> <output message="tns:addUserResponse"/> </operation> <operation name="add"> <input message="tns:add"/> <output message="tns:addResponse"/> </operation> </portType> <binding name="MyServiceImplPortBinding" type="tns:IMyService"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> <operation name="addUser"> <soap:operation soapAction=""/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> </operation> <operation name="add"> <soap:operation soapAction=""/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> </operation> </binding> <service name="MyServiceImplService"> <port name="MyServiceImplPort" binding="tns:MyServiceImplPortBinding"> <soap:address location="http://localhost:8889/testService"/> </port> </service> </definitions>