webservice精讲

webservice精讲

soap

WSDL

Java发布webservice


上一讲提到cxf使用及常见报错分析,使用cxf就不得不提webservice,毕竟cxf是用来调webservice,而提到webservice就不得不先说下soap,所以本文从soap开始到webservice

soap

Simple Object Access Protocol :简单对象访问协议

SOAP简介

SOAP是计算机之间交换信息的一个通信协议,与操作系统和编程环境无关,按照这个规范,SOAP被定义为轻量协议,以便在松散的分布式环境中用于点对点之间结构化和类型化信息的交换

SOAP不定义用于发送消息的传输协议,SOAP规范确实描述了HTTP如何用于传递SOAP消息,但它说的很明白,无论在哪一方面SOAP都不仅仅局限于HTTP协议,它能用于其他各种消息,在松散的分布式环境中点到点之间,使用XML,SOAP提供了一种简单而轻便的机制来交换结构化和类型化的消息,SOAP和XML是WEB服务体系结构的核心技术。
SOAP是一种简单的可扩展的计算机对计算机通信协议,在现有的因特网标准里起了一个杠杆的作用:XML用于消息的格式化,HTTP和其他的因特网协议用于消息的传送,它不需要特殊的防火墙配置。
SOAP消息

SOAP消息是一种从一个发送者到一个接收者的单向传输,消息经常结合起来实现请求/响应通信,所有的SOAP消息都是XML文档,他们具有自己的模式,也包括对于所有元素和属性的正确的命名空间,SOAP定义了两个命名空间,SOAP封装(envlope)和SOAP序列化(或编码),SOAP设定的一些规则比XML本身更严格

作为一个XML文档,SOAP消息由三个部分组成:SOAP封装,SOAP头,SOAP主体

简单的soap实例

文档的根元素:SOAP-ENV:Envelope
子元素SOAP-ENV:Body

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
 <m:GetLastTradePrice xmlns:m="Some-URI">
 <symbol>DIS</symbol>
</m:GetLastTradePrice>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

在这个消息体重可以看到:通过GetLastTradePrice调用了一个过程,并使用值DIS给它传递了一个参数()
注意这个封装和主题的命名空间是:http://schemas.xmlsoap.org/soap/envelope/ 而编码的命名空间是http://schemas.xmlsoap.org/soap/encoding/ 这个方法本身引用了一个用户自定义模式

SOAP消息的细节部分

SOAP封装:封装是SOAP消息中的强制顶级命令元素,可以将封装看做是包装电子邮件信息的信封,或者看做是一个用来邮寄普通信件的信封,封装的属性以及元素必须能由命名空间识别,<SOAP-ENV:Envelope>元素能够包含两个可以充当直接子元素的元素,即:<SOAP-ENV:Header>元素以及<SOAP:ENV:Body>元素,任何其他的子元素都必须位于<SOAP-ENV:Body>元素之后
SOAP头

<SOAP-ENV:Heade>是一个可选元素,如果使用它,必须成为根元素的第一个直接子元素,位于Body之前

<SOAP-ENV:Header>
 <t:Transaction xmlns:t="some-URI" SOAP-ENV:musUnderstand="1">5</t:Transaction>
</SOAP-ENV:Header>

SOAP Header元素提供了一种以分散的方式扩展消息的技术,而不需要事先了解通信双方,这种扩展的实例可以是头条目,用于验证,事务管理以及支付过程。
SOAP规范为SOAP-ENV:Header元素定义了两个属性,一个是SOAP-ENV:mustUnderstand属性,在上面的例子中含有这个属性,此属性可以有两个值:1和0(默认),1:代表消息的接收者必须能够理解头所提供的所有属性,如果不能够做到这一点,接受者必须要返回一条错误信息,并停止处理这条信息,在上面的例子中,除非接受者能够理解特定命名空间所指定的事务,否则接收者不会处理这条信息
Header元素还有一个可选的属性,即SOAP-ENV:actor属性,当一条SOAP消息通过一组SOAP中间媒介而最终传输到目的地的时候,这个属性为SOAP消息指定了中间媒介,一个SOAP中介就是一个能够处理SOAP消息并进一步指定其路由的应用程序,其功能和Internet中传输TCP/IP信息包的路由器的功能类型,但并不完全相同,如果忽略这个属性,SOAP消息的最终接受者就是第一个信息的接受者
SOAP主体

<SOAP-ENV:Body>元素含有SOAP消息的有效载荷,依据所发生的通信种类的不同Body元素可以包含RPC调用或响应,错误消息或其他的单向SOAP消息

下面显示一条SOAP消息,它向一个web服务发生RPC有效载荷

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
  <m:GetLastTradePrice xmlns:m="Some-URI">
  <symbol>DIS</symbol>
 </m:GetLastTradePrice>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
<SOAP-ENV:Body>

元素的直接子元素称为主体的条目,这些元素可以被命名空间所限制,在SOAP规范中只定义了一个主体条目元素–<SOAP-ENV:Fault>元素
SOAP错误
使用<SOAP-ENV:Fault>元素的目的是传递SOAP消息中的错误或状态信息,使用这个元素的时候,它必须只出现一次,并且必须在BODY元素中,它定义了四个子元素,如果需要更多子元素的话,可以通过在用户定义命名空间中说明来添加:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
 <faultcode>SOAP-ENV:Server</faultcode>
 <faultstring>Server Error</faultstring>
<detail>
  <e:myfaultdetails xmlns:e="some-URI">
     <message>My Application didn't work</message>
     <errorcode>1001</errorcode>
 </e:myfaultdetails>
</detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

faultcode元素用于向软件提供错误类型信息,这个元素必须位于<SOAP-ENV:Fault>元素中,定义了四种错误代码值:
1.SOAP-ENV:VersionMismatch(可能是无效的命名空间)
2.SOAP-ENV:MustUnderstand(SOAP头中的SOAP-ENV:MustUnderstand元素不能被满足
3.Client(客户所发送的消息错误,只有被修改正确之后才能被再次提交)
4.SOAP-ENV:Server(服务器处理消息过程中的错误)

faultstring元素提供了可供人们阅读的关于错误的信息,当发送<SOAP-ENV:Fault>元素的时候,<faultstring>元素必须包含在内

faultactor元素是一个可选元素,提供导致错误的系统的信息,如果SOAP的传输存在中介系统的话,此元素就特别有用

detail元素用于传输和SOAP-ENV:Body元素相关的应用程序特定的错误信息
SOAP编码和支持的类型

RPC与SOAP请求和响应实例:SOAP消息能够以单向或双向方式通信,双向通信实质上就是RPC调用和响应,信息由SOAP消息的主体元素携带

WSDL概述

Web Service Description Language 网络服务描述语言,是一种用来描述网络服务的XML格式的语言,WSDL通过将网络服务看作为对消息的一组终点处理操作,被处理的消息中包含面向 或面向过程的消息。首先抽象描述操作以及处理过程,然后绑定特定的网络或传输协议以及消息格式

wsdl的文档结构

它采用将网络服务和它们的抽象定义与实际的网络传输协议和消息格式绑定分开的方法,所以文档包含多级结构,我们将会从底部开始阅读文档,wsdl文档将服务定义为称作端口的网络终点的集合

 <service name="StockQuoteService">
   <documentation>This is a stock quote one way service</documentation>
   <port name="StockQuotePort" binding="tns:StockQuoteSoap">
     <soap:address location="mailto://subscribe@example.com"/>
   </port>
 </service>

端口是一个终点,定义为绑定和单个网络地址的结合,在上面的例子中,端口是一个带有特定SMTP地址的终点subscribe@example.com
在下面的代码中,一个绑定为一个特定的端口类型将具体的协议和数据格式联系在一起

<portType name="StockQuoteService">
 	 <operation name="SubscribeToQuotes">
 	 	<input message="tns:SubscribeToQuotes"/>
  <operation>
</portType>
<binding name="StockQuoteSoap" type="tns:StockQuotePortType">
 	<soap:bingding style="document" transport="http://example.com/smtp"/>
 <operation name="SubscribeToQuotes">
       <input message="tns:SubscribeToQuotes">
   	  	<soap:header element="xsdl:SubscriptionHeader"/>
    	</input>
 <operation>
</bingding>

上面绑定将SOAP协议指定为消息格式,SMTP为单向异步传输协议,绑定上面特定的端口类型

WSDL定义了四种格式的传输操作:

  • 单向(终点接收一条消息)
  • 请求一响应(终点接收一条信息,然后发送出对所接收消息的回应)
  • 索求一响应(终点发出一条信息,然后接收一条与之相关的信息)
  • 通知(单向,终点发送一条信息)

SOAP绑定到传输协议

SOAP没有绑定在任何传输协议上,实际上SOAP可以被几乎所有的传输协议携带,SOAP规范描述了SOAP如何应用在HTTP以及HTTP扩展框架之上,但是在规范中只是将其作为实例提及,SOAP能够和其他的协议绑定

将HTTP作为标准同步协议使用

HTTP作为一个互联网传输协议在网络中普遍存在,现在大部分的网络内容都是通过HTTP提供的,防火墙对HTTP通常非常友好,在一般情况下,HTTP信息都是通过端口80传输的,在所有的防火墙上这个端口基本都开放,HTTP可以和SSL一起使用,并可以被认证为HTTPS,通过使用这种方式,两个网络终点之间的所有网络传输都可以加密,如果SOAP使用HTTP作为其传输协议,它就可以充分利用HTTP的优点,除了通常情况下HTTPS使用端口443而非端口的80传输信息之外,上面所提及的关于HTTP的所有内容都适用HTTPS

Java发布webservice

WebService本身是多线程的,但是如果多线程不跑完客户端资源也是不会被释放的,所以使用多线程框架比较好

注意:如果导入了rpc的jar然后用jdk自带的webservice会报错

服务端接口:

@WebService
public interface ServiceTestInter {
	public String getValue(String name);
	public void setName(String name);
}

实现类:

@WebService(endpointInterface="com.test.ServiceTestInter")
public class ServiceHello implements ServiceTestInter{
	public String getValue(String name) {
		return name;
	}
	public void setName(String name) {
		System.out.println(name);
	}
}

使用jdk发布:

public class TestService {
	public static void main(String[] args) {
		Endpoint.publish("http://192.168.1.172:9001/TheService/Service", new ServiceHello());
		System.out.println("ok");
	}
}

用soap访问:

	public void soapWebService() {
		try {
			URL url = new URL(
					"http://192.168.1.172:9001/TheService/Service?wsdl");
			QName sname = new QName("http://test.com/", "ServiceHelloService");
			Service service = Service.create(url, sname);
			ServiceTestInter sh = service.getPort(ServiceTestInter.class);
			String a = sh.getValue("ij");
			System.out.println(a);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

用RPC访问

	public static void main(String[] args) {
		try {
			RPCServiceClient serviceClient = new RPCServiceClient();
			Options options = serviceClient.getOptions();
			EndpointReference targetEPR = new EndpointReference("http://192.168.1.172:9001/TheService/Service?wsdl");
			options.setAction("http://test.com/");
	        options.setTo(targetEPR);
	        Class[] classes = new Class[] { String.class };
	        //指定方法
			QName opAddEntry = new QName("http://test.com/", "getValue");
			Object[] opAddEntryArgs0 = new Object[] {"wocai"};
			String a = serviceClient.invokeBlocking(opAddEntry, opAddEntryArgs0,classes)[0].toString();
			System.out.println(a);
		} catch (AxisFault e) {
			e.printStackTrace();
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值