Web Service是一项基于XML的分布式软件实现技术,以SOAP协议作为网络通信协议,以XML文档作为数据交换格式,允许不同平台、不同语言的应用程序之间相互调用。
对于Java,已经由大量的开源框架来实现Web Service,包括Axis、Axis2和CXF等。JaveEE专门为Web Service开发指定了JAX-WS2.0规范,该规范由JAX-RPC1.1发展而来。
Web Service的特点
1)自包含性:使用者无需安装任何附加软件,只需要一种支持web和xml的编程语言即可。服务提供者值需要web服务器和soap服务器。
2)自描述性:客户端和服务端都无须关系除请求和响应消息的内容与格式之外的任何内容,消息格式与消息内容一起传播,无须外部程序辅助。
3)封装性:对使用者而言,仅能看到服务描述,而该服务的具体实现、运行平台都是透明的。
4)可编程性:并不提供图形用户界面,而是提供编程访问的API,调用者只需知道web服务器的API接口,即可使用任何平台上的任何编程语言来调用Web Service。
5)松散耦合:当web service的实现发生改变时,调用者无法感受到这种改变,只要接口没有变化,具体实现的改变时完全透明的。
6)高度的开发性:web service可以与其他的web service进行交互,具有语言和平台无关性,支持CORBA、EJB、DCOM等多种组件标准,支持各种通信协议HTTP、SMTP、FTP和RMI等
7)使用标准协议:所有公共协议都使用标准协议描述、传输和交换,这些标准协议在各种平台上完全相同。完全可以在不同供应商之间实现互操作。
8)高度整合的能力:完全屏蔽了不同平台的差异。
与web service相似的是,还有一些基于网络的系统集成技术,如DCOM(Distributed Component Object Model,分布式组件对象模型)、CORBA(Common Object Request Broker Architecture,通用对象请求代理结构)等。
Web Service主要涉及的技术有SOAP(Simple Object Access Protocol,简单对象访问协议)、WSDL(Web Service Description Language,Web Service描述语言)、UDDI(Universal Description Discovery and Integration,统一描述发现和整合协议)。
SOAP是一种具有扩展性的XML消息协议,允许一个应用程序向另一个应用程序发送XML消息,SOAP消息是从SOAP发送者传至SOAP接收者的单路消息,任何应用程序均可作为发送者或接收者。SOAP仅定义消息结构和消息处理的协议,与底层的传输协议独立。
SOAP依赖于XML文档来构建,一条SOAP消息就是一份特定的XML文档,SOAP消息包含如下3个主要元素
1)必须的Envelope根元素,SOAP消息对应的XML文档以该元素作为根元素
2)可选的Header元素,包含SOAP消息的头信息
3)必须的Body元素,包含所有的调用和响应信息
WSDL使用XML描述Web Service,包括访问和使用Web Service所必须的信息,定义改Web Service的位置、功能,以及如何通信等描述信息。
一般来说,只要能够获取Web Service对应的WSDL,就可以从中了解它所提供的服务如何调用Web Service。
一份WSDL文档通常分为两个部分
1)第一个部分定义了服务接口,在WSDL中由message元素和portType元素组成,其中message元素定义了操作的交互方式,而portType元素里则可包含任意数量的operation元素,每个operation元素代表一个允许远程调用的操作
2)第二个部分定义了服务实现,在WSDL中由binding元素和service两个元素组成,其中bingding定义使用特定的通信协议、数据编码模型和底层通信协议,将web servcie服务接口定义映射到具体实现;而service元素则包含一系列的port子元素,port子元素将把绑定机制、服务访问协议和端点地址结合在一起。
UDDI是一套信息注册规范
特定:基于web、分布式
使用UDDI,web service提供者可以对外注册web service,从而允许其他企业来调用该企业注册的web service。web service提供者通过UDDI注册中心的web页面,将所提供的web service的信息加入UDDI注册中心,该web service就可以被发现和调用。
web service使用者也可以通过UDDI注册中心查找、发现自己所需的服务,当web service使用者找到自己所需的服务之后,将自己绑定到指定的web service提供者,再根据该web serv对应的WSDL文档来调用对方的服务。
JavaEE中与Web Service相关的规范还有
1)JAXB2.0(Java Architecture for XML Binding):该规范提供了一套简单的API,开发者可以通过这套API完成XML Schema和Java之间的绑定。JAXB规范允许程序根据XML Schema生成Java类。在该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并允许将Java对象树的内容重新写到XML实例文档中。
2)SAAJ(SOAP with Attachments API for Java):该规范主要提供了一组创建和操作SOAP消息的API。SAAJ API位于javax.xml.soap包下,这套API包含了代表SOAP消息中Envelop元素、Body元素、Fault元素的接口。开发者可以直接利用这套API来创建和操作SOAP消息。
3)JAXR1.0(Java API for XML Registries):该规范提供了一套标准的Java API来访问各种XML注册表(XML Registry)。XML注册表的重要部分就是UDDI项目,UDDI项目一般由厂商联盟共同开发。不同的XML注册表之间的差异还是比较大的,而JAXR则允许开发整采用统一的API来操作不同的XML注册表实现,通过JAXR可以编写在各个注册表之间自由移植的客户机程序
4)Web Service Metadata for the Java Platform:为Java平台的Web Service提供注解支持。允许开发者通过为POJO、无状态Session Bean添加一些额外的注解,即可将他们包装web service
5)JAXM(Java APIs for XML Messaging):JAXM是一套通过XML(以及SOAP)发送和接收消息的API,JAXM不仅支持使用同步消息,也支持使用异步消息。JAXM规范包括消息、连接、消息提供者、JAXM客户端和JAXM服务器端等几个部分。
a)JAXM消息使用SOAP消息标准,即可包括附件也可不包括附件
b)JAXM连接分为两种
直接连接:消息发送者直接将消息发送给消息接收者
间接连接:消息发送者通过消息提供者把消息转发给消息接收者
c)消息提供者负责为消息发送者处理消息的传送和路由
d)JAXM客户端向接收者发送消息,最终接收者一般是JAXM服务器端
e)JAXM服务器端是JAXM消息的消费者,服务器端读取并处理JAXM客户端所发送的消息。
使用JAX-WS2.0开发web service
API在javax.jws包下
@WebService一般用于修饰EJB3的Bean实现类,用于将无状态Session Bean暴露成WebService
属性说明
1)name,非必须,指定名称,该名称将作为WSDL的portType元素的name属性值,如果没有指定,则默认为Bean接口或Bean实现类的名称
2)serviceName,非必须,指定service名称。只有当该注解修饰Bean实现类时,才允许指定该属性,该属性指定的名称将作为WSDL的service元素的name属性值,默认为Bean实现类的名称加上Service后缀
3)portName:非必须,指定port名称
4)targetNamespace:非必须,指定WSDL的目标命名空间,默认根据Java包名来生成WSDL的目标命名空间
5)endpointInterface:非必须,默认服务器自动生成服务器端口接口ESI,这个名字是厂商专有的
6)wsdlLocation:非必须,指定所需WSDL文件的URL,默认EJB容器会自动为WebService生成所需的URL。如果希望EJB使用自定义的WSDL文件,可以通过该属性来指定WSDL文件所在的位置。如果用户指定WSDL文件与实现类之间存在任何不一致的地方,容器就会生成相应的部署错误。
@Stateless
@WebService(name = "hello",
serviceName = "firstWS",
portName = "helloPort",
targetNamespace = "http://www.kingdz.org")
public class HelloBean {
public String hello(String name) {
return name + " hello";
}
}
部署之后的DSL为
<definitions name='firstWS' targetNamespace='http://www.kingdz.org' xmlns='http://schemas.xmlsoap.org/wsdl/' xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/' xmlns:tns='http://www.kingdz.org' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
<types>
<xs:schema targetNamespace='http://www.kingdz.org' version='1.0' xmlns:tns='http://www.kingdz.org' xmlns:xs='http://www.w3.org/2001/XMLSchema'>
<xs:element name='hello' type='tns:hello'/>
<xs:element name='helloResponse' type='tns:helloResponse'/>
<xs:complexType name='hello'>
<xs:sequence>
<xs:element minOccurs='0' name='arg0' type='xs:string'/>
</xs:sequence>
</xs:complexType>
<xs:complexType name='helloResponse'>
<xs:sequence>
<xs:element minOccurs='0' name='return' type='xs:string'/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</types>
<message name='hello_helloResponse'>
<part element='tns:helloResponse' name='helloResponse'></part>
</message>
<message name='hello_hello'>
<part element='tns:hello' name='hello'></part>
</message>
<portType name='hello'>
<operation name='hello' parameterOrder='hello'>
<input message='tns:hello_hello'></input>
<output message='tns:hello_helloResponse'></output>
</operation>
</portType>
<binding name='helloBinding' type='tns:hello'>
<soap:binding style='document' transport='http://schemas.xmlsoap.org/soap/http'/>
<operation name='hello'>
<soap:operation soapAction=''/>
<input>
<soap:body use='literal'/>
</input>
<output>
<soap:body use='literal'/>
</output>
</operation>
</binding>
<service name='firstWS'>
<port binding='tns:helloBinding' name='helloPort'>
<soap:address location='http://127.0.0.1:8080/Hello/HelloBean'/>
</port>
</service>
</definitions>