一、Web Service定义
二、为什么使用Web Service
三、Web Service的缺点
四、Web Service 元素
SOAP协议 = HTTP协议 + XML数据格式
SOAP协议定义了SOAP消息的格式,SOAP协议是基于HTTP协议的,SOAP也是基于XML和XSD的,XML是SOAP的数据编码方式。打个比喻:HTTP就是普通公路,XML就是中间的绿色隔离带和两边的防护栏,SOAP就是普通公路经过加隔离带和防护栏改造过的高速公路。
<? xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Header>
...
</soap:Header>
<soap:Body>
...
<soap:Fault>
...
</soap:Fault>
</soap:Body>
</soap:Envelope>
- xmlns:soap属性:值必须是http://www.w3.org/2001/12/soap-envelope。
- encodingStyle 属性:语法:soap:encodingStyle="URI" 。encodingStyle 属性用于定义文档中使用的数据类型。此属性可出现在任何 SOAP 元素中,并会被应用到元素的内容及元素的所有子元素上。
- actor 属性:语法soap:actor="URI",通过沿着消息路径经过不同的端点,SOAP 消息可从某个发送者传播到某个接收者。并非 SOAP 消息的所有部分均打算传送到 SOAP 消息的最终端点,不过,另一个方面,也许打算传送给消息路径上的一个或多个端点。SOAP 的 actor 属性可被用于将 Header 元素寻址到一个特定的端点。
- mustUnderstand 属性:语法soap:mustUnderstand="0|1",可用于标识标题项对于要对其进行处理的接收者来说是强制的还是可选的。假如您向 Header 元素的某个子元素添加了 "mustUnderstand="1",则要求处理此头部的接收者必须认可此元素。
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:axis="http://ws.apache.org/axis2">
<soapenv:Header/>
<soapenv:Body>
<axis:sayHelloToPerson>
<!--Optional:-->
<name>Mike</name>
</axis:sayHelloToPerson>
</soapenv:Body>
</soapenv:Envelope>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:sayHelloToPersonResponse xmlns:ns="http://ws.apache.org/axis2">
<return>hello,Mike</return>
</ns:sayHelloToPersonResponse>
</soapenv:Body>
</soapenv:Envelope>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ns1="http://org.apache.axis2/xsd" xmlns:ns="http://ws.apache.org/axis2" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" targetNamespace="http://ws.apache.org/axis2">
<wsdl:types>
<xs:schema attributeFormDefault="qualified" elementFormDefault="unqualified" targetNamespace="http://ws.apache.org/axis2">
<xs:element name="sayHelloToPerson">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="name" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="sayHelloToPersonResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="return" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="sayHello">
<xs:complexType>
<xs:sequence/>
</xs:complexType>
</xs:element>
<xs:element name="sayHelloResponse">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="return" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<wsdl:message name="sayHelloRequest">
<wsdl:part name="parameters" element="ns:sayHello"/>
</wsdl:message>
<wsdl:message name="sayHelloResponse">
<wsdl:part name="parameters" element="ns:sayHelloResponse"/>
</wsdl:message>
<wsdl:message name="sayHelloToPersonRequest">
<wsdl:part name="parameters" element="ns:sayHelloToPerson"/>
</wsdl:message>
<wsdl:message name="sayHelloToPersonResponse">
<wsdl:part name="parameters" element="ns:sayHelloToPersonResponse"/>
</wsdl:message>
<wsdl:portType name="HelloServicePortType">
<wsdl:operation name="sayHello">
<wsdl:input message="ns:sayHelloRequest" wsaw:Action="urn:sayHello"/>
<wsdl:output message="ns:sayHelloResponse" wsaw:Action="urn:sayHelloResponse"/>
</wsdl:operation>
<wsdl:operation name="sayHelloToPerson">
<wsdl:input message="ns:sayHelloToPersonRequest" wsaw:Action="urn:sayHelloToPerson"/>
<wsdl:output message="ns:sayHelloToPersonResponse" wsaw:Action="urn:sayHelloToPersonResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="HelloServiceSoap11Binding" type="ns:HelloServicePortType">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<wsdl:operation name="sayHello">
<soap:operation soapAction="urn:sayHello" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="sayHelloToPerson">
<soap:operation soapAction="urn:sayHelloToPerson" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="HelloServiceSoap12Binding" type="ns:HelloServicePortType">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<wsdl:operation name="sayHello">
<soap12:operation soapAction="urn:sayHello" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="sayHelloToPerson">
<soap12:operation soapAction="urn:sayHelloToPerson" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="HelloServiceHttpBinding" type="ns:HelloServicePortType">
<http:binding verb="POST"/>
<wsdl:operation name="sayHello">
<http:operation location="sayHello"/>
<wsdl:input>
<mime:content type="application/xml" part="parameters"/>
</wsdl:input>
<wsdl:output>
<mime:content type="application/xml" part="parameters"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="sayHelloToPerson">
<http:operation location="sayHelloToPerson"/>
<wsdl:input>
<mime:content type="application/xml" part="parameters"/>
</wsdl:input>
<wsdl:output>
<mime:content type="application/xml" part="parameters"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="HelloService">
<wsdl:port name="HelloServiceHttpSoap11Endpoint" binding="ns:HelloServiceSoap11Binding">
<soap:address location="http://localhost:8080/axis2/services/HelloService.HelloServiceHttpSoap11Endpoint/"/>
</wsdl:port>
<wsdl:port name="HelloServiceHttpSoap12Endpoint" binding="ns:HelloServiceSoap12Binding">
<soap12:address location="http://localhost:8080/axis2/services/HelloService.HelloServiceHttpSoap12Endpoint/"/>
</wsdl:port>
<wsdl:port name="HelloServiceHttpEndpoint" binding="ns:HelloServiceHttpBinding">
<http:address location="http://localhost:8080/axis2/services/HelloService.HelloServiceHttpEndpoint/"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
五、Web Service 实现
- 这个类必须是public类
- 这些类不能是final的或者abstract
- 这个类必须有一个公共的默认构造函数
- 这个类绝对不能有finalize()方法
package com.tsingsoft.service;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
/**
* 提供WebService服务的类
*/
@WebService(name = "HelloService", targetNamespace = "http://www.tsingsoft.com/wstest", serviceName = "HelloService")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public class HelloService {
/**
* sayHello
* @return
*/
@WebMethod(operationName = "sayHello", action = "sayHello", exclude = false)
@WebResult(name = "returnWord")
// 自定义该方法返回值在WSDL中相关的描述
public String sayHello() {
return "Hello";
}
/**
* sayHelloToPerson
* @param name
* @return
*/
@WebMethod(operationName = "sayHelloToPerson", action = "sayHelloToPerson", exclude = false)
@WebResult(name = "returnWord")
// 自定义该方法返回值在WSDL中相关的描述
public String sayHelloToPerson(@WebParam(name = "name") String name) {
return "Hello:" + name;
}
}
package com.tsingsoft.service;
import javax.xml.ws.Endpoint;
/**
* 启动web services服务
*
* @author 陶金贵
* @since 2015-3-2 下午2:07:41
* @version
*/
public class StartServer {
/**
* @param args
*/
public static void main(String[] args) {
/*
* 生成Example 服务实例
*/
HelloService serverBean = new HelloService();
/*
* 发布Web Service到http://localhost:8080/hello地址
*/
Endpoint.publish("http://localhost:8080/hello", serverBean);
}
}
package com.tsingsoft.client;
/**
* Web Service 客户端
*
* @author 陶金贵
* @since 2015-3-11 下午1:48:25
* @version
*/
public class HelloClient {
/**
* @param args
*/
public static void main(String[] args) {
// 初始化服务框架类
HelloService_Service service = new HelloService_Service();
// 或者本地服务借口的实例
HelloService server = (HelloService) service.getHelloServicePort();
try {
// 调用web service的sayHello方法
System.out.println("sayHello的返回值:" + server.sayHello());
// 调用web service的sayHello方法
System.out.println("sayHelloToPerson的返回值:" + server.sayHelloToPerson("Mike"));
}
catch (Exception e) {
e.printStackTrace();
}
}
}
2)Web Service 服务端
/**
* WebService 服务端
* @author 陶金贵
* @since 2015-3-2 上午11:32:26
* @version
*/
public class HelloService {
public String sayHello() {
return "hello";
}
public String sayHelloToPerson(String name) {
if (name == null) {
name = "nobody";
}
return "hello," + name; }
}
Web Service 服务端有两种发布方式:
(1)用POJO形式发布(POJO类不能使用package关键字声明包)
编译HelloService类后,将HelloService.class文件放到<Tomcat安装目录>\webapps\axis2\WEB-INF\pojo目录中(如果没有pojo目录,则建立该目录)。现在我们已经成功将HelloService类发布成了WebService。
在浏览器地址栏中输入URL显示Service发布情况: http://localhost:8080/axis2/services/listServices
(2)使用services.xml配置文件发布
<?xml version="1.0" encoding="UTF-8"?>
<service name="HelloServiceNew">
<description>
Web Service例子
</description>
<parameter name="ServiceClass">
com.tsingsoft.webservice.HelloService
</parameter>
<messageReceivers>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
</messageReceivers>
</service>
jar cvf ws.aar .
3)Web Service 客户端
import javax.xml.namespace.QName;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;
/**
* WebService 客户端
* @author 陶金贵
* @since 2015-3-2 上午11:57:06
* @version
*/
public class HelloClient {
public static void main(String args[]) throws AxisFault {
// 使用RPC方式调用WebService
RPCServiceClient serviceClient = new RPCServiceClient();
Options options = serviceClient.getOptions();
// 指定调用WebService的URL
EndpointReference targetEPR = new EndpointReference(
"http://localhost:8080/axis2/services/HelloService?wsdl");
options.setTo(targetEPR);
// 指定要调用的sayHelloToPerson方法及WSDL文件的命名空间
QName opAddEntry = new QName("http://ws.apache.org/axis2", "sayHelloToPerson");
// 指定sayHelloToPerson方法的参数值
Object[] opAddEntryArgs = new Object[] { "Mike" };
// 指定sayHelloToPerson方法返回值的数据类型的Class对象
Class[] classes = new Class[] { String.class };
// 调用sayHelloToPerson方法并输出该方法的返回值
String result = (String)serviceClient.invokeBlocking(opAddEntry, opAddEntryArgs, classes)[0];
System.out.println(result);
}
}
六、Web Service测试工具:SoapUI
1. SoapUI介绍
SoapUI是一个开源测试工具,通过soap/http来检查、调用、实现Web Service的功能/负载/符合性测试。
2. 创建工程
安装并运行SoapUI之后,你就可以创建第一个SoapUI工程了。程序第一次打开时,左侧导航面板上,自动有一个空的Projects工程。右击左侧导航面板中的工作空间节点“Projects”,选择 “New Soap Project”。
页面弹出“New SoapUI Project”TAB页,填入Project Name,Initial WSDL/WADL可填入URL地址或直接导入WSDL文件,点击确定,显示该Web Service 提供的全部方法。
双击HelloToPerson下的Request1,弹出请求编辑器,请求编辑器分为三部分:
1)顶部的工具栏,包含一组请求相关的动作、操作
2)左边是请求区域
3)右边是响应区域
在请求编辑框内,“?”表示可以传递的参数,修改“?”并点击左上角绿色三角形按钮,提交请求,在右边则会显示响应的内容
参考资料:
Web Service学习笔记 :http://blog.csdn.net/qjyong/article/details/2148558
为什么使用WebService :http://blog.csdn.net/superjj01/article/details/5270227