下载cxf: http://cxf.apache.org/
服务端
与jdk开发WebService不同之处,加入cxf的jar包即可,其它不需要改动
新建一个项目
HelloWS接口
- package com.me.ws;
- import javax.jws.WebMethod;
- import javax.jws.WebService;
- /*
- * SEI
- */
- @WebService
- public interface HelloWS {
- @WebMethod
- public String sayHello(String name);
- }
- package com.me.ws;
- import javax.jws.WebService;
- /*
- * SEI的实现
- */
- @WebService
- public class HelloWSImpl implements HelloWS {
- @Override
- public String sayHello(String name) {
- System.out.println("server sayHello()" + name);
- return "Hello " + name;
- }
- }
发布Web Service
- package com.me.ws.server;
- import javax.xml.ws.Endpoint;
- import com.me.ws.HelloWSImpl;
- /*
- * 发布Web Service
- */
- public class ServerTest {
- public static void main(String[] args) {
- String address = "http://192.168.1.104:1002/cxf/hellows";
- Endpoint.publish(address, new HelloWSImpl());
- System.out.println("发布webservice成功!");
- }
- }
使用eclipse工具测试
开发客户端
新建项目
使用cxf工具包生成客户端代码
首先要配置环境变量
在path环境变量:D:\java\tools\apache-cxf-3.1.6\apache-cxf-3.1.6\bin
打开cmd
刷新项目
测试代码
package com.me.ws.test;
import com.me.ws.HelloWS;
import com.me.ws.HelloWSImplService;
public class clientTest {
public static void main(String[] args) {
HelloWSImplService factory = new HelloWSImplService();
HelloWS helloWS = factory.getHelloWSImplPort();
String hello = helloWS.sayHello("jack");
System.out.println(hello);
}
}
wsdl文档结构
<definitions>
<types>
<schema>
<element>
</types>
<message>
<part>
</message>
<portType>
<operation>
<input>
<output>
</portType>
<binding>
<operation>
<input>
<output>
</binding>
<service>
<port>
<address>
</service>
</definitions>
types - 数据类型(标签)定义的容器,里面使用schema定义了一些标签结构供message引用
message - 通信消息的数据结构的抽象类型化定义。引用types中定义的标签
operation - 对服务中所支持的操作的抽象描述,一个operation描述了一个访问入口的请求消息与响应消息对。
portType - 对于某个访问入口点类型所支持的操作的抽象集合,这些操作可以由一个或多个服务访问点来支持。
binding - 特定端口类型的具体协议和数据格式规范的绑定。
service- 相关服务访问点的集合
port - 定义为协议/数据格式绑定与具体Web访问地址组合的单个服务访问点。
wsdl深入分析
<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://ws.me.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="HelloWSImplService" targetNamespace="http://ws.me.com/">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://ws.me.com/" elementFormDefault="unqualified" targetNamespace="http://ws.me.com/" version="1.0">
<!--
//用于请求
<sayHello>
<arg0>string</arg0>
</sayHello>
<q0:sayHello>
<arg0>BB</arg0>
</q0:sayHello>
//用于响应
<sayHelloResponse>
<return>string</return>
</sayHelloResponse>
<ns2:sayHelloResponse">
<return>Hello BB</return>
</ns2:sayHelloResponse>
-->
<xs:element name="sayHello" type="tns:sayHello" />
<xs:element name="sayHelloResponse" type="tns:sayHelloResponse" />
<xs:complexType name="sayHello">
<xs:sequence>
<xs:element minOccurs="0" name="arg0" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="sayHelloResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<!--
message: 用来定义消息的结构 soap消息
part : 指定引用types中定义的标签片断
-->
<wsdl:message name="sayHelloResponse">
<wsdl:part element="tns:sayHelloResponse" name="parameters">
</wsdl:part>
</wsdl:message>
<wsdl:message name="sayHello">
<wsdl:part element="tns:sayHello" name="parameters">
</wsdl:part>
</wsdl:message>
<!--
portType: 用来定义服务器端的SEI
operation : 用来指定SEI中的处理请求的方法
input : 指定客户端应用传过来的数据, 会引用上面的定义的<message>
output : 指定服务器端返回给客户端的数据, 会引用上面的定义的<message>
-->
<wsdl:portType name="HelloWS">
<wsdl:operation name="sayHello">
<wsdl:input message="tns:sayHello" name="sayHello">
</wsdl:input>
<wsdl:output message="tns:sayHelloResponse" name="sayHelloResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<!--
binding : 用于定义SEI的实现类
type属性: 引用上面的<portType>
<soap:binding style="document"> : 绑定的数据是一个document(xml)
operation : 用来定义实现的方法
<soap:operation style="document" /> 传输的是document(xml)
input: 指定客户端应用传过来的数据
<soap:body use="literal" /> : 文本数据
output : 指定服务器端返回给客户端的数据
<soap:body use="literal" /> : 文本数据
-->
<wsdl:binding name="HelloWSImplServiceSoapBinding" type="tns:HelloWS">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="sayHello">
<soap:operation soapAction="" style="document" />
<wsdl:input name="sayHello">
<soap:body use="literal" />
</wsdl:input>
<wsdl:output name="sayHelloResponse">
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<!--
service : 一个webservice的容器
name属性: 它用一指定客户端容器类
port : 用来指定一个服务器端处理请求的入口(就SEI的实现)
binding属性: 引用上面定义的<binding>
address : 当前webservice的请求地址
-->
<wsdl:service name="HelloWSImplService">
<wsdl:port binding="tns:HelloWSImplServiceSoapBinding" name="HelloWSImplPort">
<soap:address <span class="html-attribute-name" style="font-family: monospace; font-size: 13px;">location</span><span style="color: rgb(136, 18, 128); font-family: monospace; font-size: 13px;">="</span><span class="html-attribute-value" style="font-family: monospace; font-size: 13px;">http://192.168.1.104:1002/cxf/hellows</span><span style="color: rgb(136, 18, 128); font-family: monospace; font-size: 13px;">"</span> />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
一次Web service请求的流程
一次web service请求的本质:
1)客户端向服务器端发送了一个soap消息(http请求+xml片断)
2) 服务器端处理完请求后, 向客户端返回一个soap消息
那么它的流程是怎样的呢?