选自javaee技术体系中的webservice技术
WSDL定义
WSDL是一个用于精确描述Web服务的文档,WSDL文档是一个遵循WSDL XML模式的XML文档。WSDL 文档将Web服务定义为服务访问点或端口的集合。在 WSDL 中,由于服务访问点和消息的抽象定义已从具体的服务部署或数据格式绑定中分离出来,因此可以对抽象定义进行再次使用:消息,指对交换数据的抽象描述;而端口类型,指操作的抽象集合。用于特定端口类型的具体协议和数据格式规范构成了可以再次使用的绑定。将Web访问地址与可再次使用的绑定相关联,可以定义一个端口,而端口的集合则定义为服务。
WSDL结构示意图如下:
一个WSDL文档通常包含7个重要的元素,即types、import、message、portType、operation、binding、service元素。这些元素嵌套在definitions元素中,definitions是WSDL文档的根元素。文章的下一部分将会详细介绍WSDL的基本结构。
具体作用说明如下:
- Types - 数据类型定义的容器,它使用某种类型系统(一般地使用XML Schema中的类型系统)。
- Message - 通信消息的数据结构的抽象类型化定义。使用Types所定义的类型来定义整个消息的数据结构。
- Operation - 对服务中所支持的操作的抽象描述,一般单个Operation描述了一个访问入口的请求/响应消息对。
- PortType - 对于某个访问入口点类型所支持的操作的抽象集合,这些操作可以由一个或多个服务访问点来支持。
- Binding - 特定端口类型的具体协议和数据格式规范的绑定。
- Port - 定义为协议/数据格式绑定与具体Web访问地址组合的单个服务访问点。
- Service- 相关服务访问点的集合。
WSDL的约束文档schema约束文档链接:http://schemas.xmlsoap.org/wsdl/。
分析
已笔者写的webservice举例来说明,接口如下:
@WebService
public interface IWebServiceTest {
@WebMethod
public void test();
@WebMethod
public String fun(String name);
}
发布后生成的wsdl文件内容如下:
<definitions targetNamespace="http://impl.webservice.lgy.com/" name="WebServiceTestImplService">
<types>
<xsd:schema>
<xsd:import namespace="http://impl.webservice.lgy.com/" schemaLocation="http://127.0.0.1:7777/test?xsd=1"/>
</xsd:schema>
</types>
<message name="test">
<part name="parameters" element="tns:test"/>
</message>
<message name="testResponse">
<part name="parameters" element="tns:testResponse"/>
</message>
<message name="fun">
<part name="parameters" element="tns:fun"/>
</message>
<message name="funResponse">
<part name="parameters" element="tns:funResponse"/>
</message>
<portType name="WebServiceTestImpl">
<operation name="test">
<input wsam:Action="http://impl.webservice.lgy.com/WebServiceTestImpl/testRequest" message="tns:test"/>
<output wsam:Action="http://impl.webservice.lgy.com/WebServiceTestImpl/testResponse" message="tns:testResponse"/>
</operation>
<operation name="fun">
<input wsam:Action="http://impl.webservice.lgy.com/WebServiceTestImpl/funRequest" message="tns:fun"/>
<output wsam:Action="http://impl.webservice.lgy.com/WebServiceTestImpl/funResponse" message="tns:funResponse"/>
</operation>
</portType>
<binding name="WebServiceTestImplPortBinding" type="tns:WebServiceTestImpl">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="test">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="fun">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="WebServiceTestImplService">
<port name="WebServiceTestImplPort" binding="tns:WebServiceTestImplPortBinding">
<soap:address location="http://127.0.0.1:7777/test"/>
</port>
</service>
</definitions>
根据生成的客户端,调用方式如下:
调用方式一:
//调用方式一:
WebServiceTestImplService wti = new WebServiceTestImplService();
WebServiceTestImpl webServiceTestImplPort = wti.getWebServiceTestImplPort();
webServiceTestImplPort.fun("aaa");
webServiceTestImplPort.test();
根据service节点下的name生成实例,在获取端口类型获取端口portType节点,根据该节点下的方法描述进行调用里面的方法。
调用方式二:
URL url = new URL("http://127.0.0.1:7777/test?wsdl");
// Qnameqname是qualified name 的简写
// 2.构成:由名字空间(namespace)前缀(prefix)以及冒号(:),还有一个元素名称构成
QName qname = new QName("http://impl.webservice.lgy.com/", "WebServiceTestImplService");
Service service = Service.create(url, qname);
WebServiceTestImpl ms = service.getPort(WebServiceTestImpl.class);
ms.fun("aaa");
ms.test();
同上原理差不多,根据QName指定命名空间,已经service节点的实例,在获取对应端口类型进行调用该端口的方法。
service节点通过binding="tns:WebServiceTestImplPortBinding"找到binding节点,二binding节点根据type="tns:WebServiceTestImpl"到找到端口类型节点。
调用方式三:
使用js的方式调用,采用的是http的方式。开源项目的地址如下:
https://github.com/doedje/jquery.soap