WebService原理及重要术语
⼀:WebService简介
1:WebService介绍
  WebService是⼀个平台独⽴的、低耦合的、⾃包含的、基于可编程的web应⽤程序,可使⽤开放的XML来描述、发布、发现、协调和配置这些应⽤程序,⽤于开发分布式交互操作的应⽤程序。
  WebService技术,能运⾏在不同机器上的不同应⽤⽆须借助附加的、专门的第三⽅软件或硬件,就可相互交换数据或集
成。依据WebService规范实施的应⽤之间,⽆论它们所使⽤的语⾔、平台或内部协议是什么,都可以相互交换数据。
  这么说吧,其实WebService就是⼀种跨编程语⾔和跨操作系统平台的远程调⽤技术(RPC的⼀种实现⽅式)。所谓可跨编程语⾔,就是说服务端程序和客户端程序可以以不同的语⾔编写也可以利⽤WebService互相调⽤;跨操作系统平台则是指服务端程序和客户端程序可以在不同的操作系统上运⾏。远程调⽤,就是⼀台计算机的应⽤可以调⽤其他计算机上的应⽤。例如:我⾃⼰编写⼀个⽹站,⾥⾯想要个天⽓预报的功能,这个时候我肯定去调⽤⽓象局的接⼝服务⽽不是我⾃⼰发射卫星来监测天⽓,再
引⼊我⽹站⾥。
2:为什么使⽤WebService
  WebService能解决跨平台调⽤、跨语⾔调⽤、远程调⽤(RPC)
  以各个⽹站显⽰天⽓预报功能为例,⽓象中⼼的管理系统将收集的天⽓信息并将数据暴露出来(通过WebService Server),⽽各⼤站点的应⽤就去调⽤它们得到天⽓信息并以不同的样式去展⽰(WebService Client),我们⽹站虽然提供了天⽓预报的服务,但其实它们什么也没有做,只是简单的调⽤了⼀下⽓象中⼼服务器服务接⼝⽽已。
3:WebService原理及重要术语
  XML、SOAP、WSDL 是构成WebService平台的三⼤技术
⼀:基本术语
  UDDI:Universal Description, Discovery, and Integration(统⼀描述、发现和集成)
  UDDI是OASIS发起的⼀个开放项⽬,它使企业在互联⽹上可以互相发现并且定义业务之间的交互。
  SOAP:simple object  access protocal(简单对象访问协议)
  ①:是⼀种简单的、基于HTTP和XML的协议, ⽤于在WEB上交换结构化的数据,结构化数据实际上就是xml的数据
  ②:SOAP消息:请求消息和响应消息
  ③:HTTP+XML⽚断
  WSDL:web service definition language(WebService定义语⾔)
  ①:对应⼀种类型的⽂件.wsdl
  ②:定义了WebService的服务器端与客户端应⽤交互传递请求和响应数据的格式和⽅式
  ③:⼀个WebService对应⼀个唯⼀的wsdl⽂档(理解为接⼝说明书)
  SEI:WebService EndPoint Interface(终端,WebService的终端接⼝)
  ①:就是WebService服务器端⽤来处理请求的接⼝;我们可以理解为是xxxWebService的各个xxxWebServiceImpl实现类
  CXF:Celtix + XFire,⼀个apache的⽤于开发webservice服务器端和客户端的框架
WebService基本原理
①:WebService是采⽤HTTP协议在客户端和服务端之间传输数据
②:WebService传输的数据是使⽤XML封装后再传输交互,XML的优点在于它的跨平台性(因为市⾯上的语⾔基本上都⽀持xml解析)
③:WebService发送的请求内容和响应内容都采⽤XML格式封装,并增加了⼀些特定的HTTP消息头,以说明HTTP消息的内容格式,这些特定
  的HTTP消息头和XML内容格式就是SOAP协议规定的
④:WebService服务器端⾸先要通过⼀个WSDL⽂件来说明⾃⼰有什么服务可以对外调⽤。简单的说,WSDL就像是⼀个说明书,⽤于
  描述WebService及其⽅法、参数和返回值。 WSDL⽂件保存在Web服务器上,通过⼀个url地址就可以访问到它。客户端要调⽤
  ⼀个WebService服务之前,要知道该服务的WSDL⽂件的地址。
⑤:WebService交互的过程就是,WebService遵循SOAP协议通过XML封装数据,然后由Http协议来传输数据。
注:WebService服务提供商可以通过两种⽅式来暴露它的WSDL⽂件地址:
1:注册到UDDI服务器,以便被⼈查
2:直接告诉给客户端调⽤者
总结:要想编写WebService接⼝就⼀定要以SOAP请求来传输数据(HTTP+XML),编写完成后把服务暴露到UDDI服务器上,这时调⽤者
  可以通过指定的URL来⽣成WSDL
4:WebService两种开发⽅式
1:JAX-WS(Java API for XML Web Service):
JAX-WS规范是⼀组XML web services的JAVA API,JAX-WS允许开发者可以选择RPC-oriented或者message-oriented
  来实现⾃⼰的web services。
  在JAX-WS中,⼀个远程调⽤可以转换为⼀个基于XML的协议例如SOAP,在使⽤JAX-WS过程中,开发者不需要编写任何⽣成和处
  理SOAP消息的代码。JAX-WS的运⾏时实现会将这些API的调⽤转换成为对应的SOAP消息
  缺点:我们必须借助WSDL说明书来⽣成⼀个java客户端代码,后期就像调⽤⽅法⼀样调⽤
2:JAX-RS(Java API for RESTful Web Servicecs):
是⼀个Java编程语⾔的应⽤程序接⼝,⽀持按照表述性状态转移(REST)架构风格创建Web服务。JAX-RS使⽤了JavaSE5引⼊
优点:不⽤编写客户端,只需要服务端提供RESTFul的URL调⽤即可
⼆:WebService服务端和客户端的开发(了解)
  注:本章节案例⽤的全部注解在后⾯专门介绍(此章只是⼊门案例,具体在⽂章后⾯集成说明)
  此章⾥⾯的⽅式了解即可,因为在实际开发中都是以Spring来集成CXF⽅式开发服务端和客户端;
  JAX-WS就是我们俗称的JDK(JDK版本1.6+才可以)开发,因为JDK⾃带这种⽅式开发客户端和服务端
  Apache CXF = Celtix + XFire,ApacheCXF 的前⾝叫 Apache CeltiXfire,现在已经正式更名为 Apache CXF 了,以下简称为 CXF。CXF 继承了 Celtix 和XFire 两⼤开源项⽬的精华,提供了对 JAX-WS 全⾯的⽀持,并且提供了多种 Binding 、DataBinding、Transport 以及各种 Format 的⽀持,并且可以根据实际项⽬的需要,采⽤代码优先(Code First)或者 WSDL 优先(WSDL First)来轻松地实现 Web Services 的发布和使⽤。
1:使⽤JAX-WS开发服务端(熟悉流程)
基本实体类Student、Dog
SEI接⼝及接⼝实现类
服务发布
  完成到这⼀步后我们的服务端就编写好了,接下来我们就要测试我们当前发布的服务是否可以访问,这时候我们就要访问我们当前编写服务的WSDL说明书,WSDL服务访问必须是我们发布的服务地址后加上?wsdl才可访问;我们通过阅读wsdl可以确定客户端要怎么调⽤该服务端,wsdl定义了接⼝、⽅
法、参数、返回值,告知我们以指定规范来调⽤服务端
  说明:使⽤JDK⾃带的WebService是没有的,在这⾥⼤家知道它没有功能即可
2:使⽤JAX-WS开发客户端(熟悉流程)
  其实客户端调⽤服务端的⽅法有很多,但在⼤多情况下我们都是⽤⼯具⽣成客户端代码,这⾥我们就⽤到⼯具(JDK的bin ⽬录下⾃带此⼯具,因为JAX-WS写的服务本⾝就是JDK拥有的,所以也有⽣成客户端⼯具)是jdk⾃带的webservice客户端⼯具可以根据wsdl⽂档⽣成客户端调⽤代码(java代码)。当然,⽆论服务器端的WebService是⽤什么语⾔写的,都可以⽣成调⽤webservice的客户端代码客户端调⽤ TestClient类
3:使⽤CXF_WS开发服务端(WS⽅式)
基本实体类Student、Dog
SEI接⼝及接⼝实现类
TestMain服务端发布代码
log4j.properties⽇志配置⽂件
4:使⽤CXF_WS开发客户端(WS⽅式)
  在上⾯我们介绍了JDK⾃带的执⾏⽂件,其实⽤此⼯具也是可以⽣成CXF_WS的客户端代码,但是我们既然都知道是CXF 写的了,何必不⽤CXF⾃家的客户端⽣成⼯具呢?所以我就介绍⼀些CXF特有的⽣成客户端⼯具 wsdl2java
  cxf是Apache的,所以我们要去下载⼀个按照⾃⼰合适的版本来,我下载的是apache-cxf-3.4.4.zip ,解压后在bin⽬录下就有wsdl2java ⼯具,此时如果想随时随地cmd使⽤我们就得去配置环境变量,⼤家⾃⼰像maven的配置⽅式配置,保证可以到cxf的bin⽬录⾥⾯(我就不配置了,直接访问到此⽂件夹⾥)
基本使⽤wsdl2java
基本语法:wsdl2java -d '⽣成客户端的位置' -client '?wsdl地址或者wsdl⽂件'
-p:指定其wsdl的命名空间,也就是要⽣成代码的包名
-d:指定要产⽣代码所在⽬录
-client:⽣成客户端测试web service的代码
-server:⽣成服务器启动web service的代码
-impl:⽣成web service的实现代码
-ant:⽣成l⽂件
-all:⽣成所有开始端点代码:types,service proxy,,service interface, server mainline,
client mainline, implementation object, and an l file.
如我当前使⽤:
wsdl2java -d C:\Users\xiaof\Desktop\client -client 127.0.0.1:9999/WebService/student?wsdl
wsdl2java -d C:\Users\xiaof\Desktop\client -client C:\Users\xiaof\Desktop\student.wsdl
  说到这,我们就可以⽣成客户端代码在我们的项⽬中了,关于cxf_ws的项⽬我们要引⼊⼀些指定的坐标
客户端调⽤代码
5:使⽤CXF_RS开发服务端(restful⽅式)
  此结构与CXF-WS⽬录是⼀样的定义,只是代码改变,此⽅式是没有wsdl说明书的,客户端⽆需使⽤WSDL来⽣成客户端代码可以直接调⽤
基本实体类Student、Dog
SEI接⼝及接⼝实现类
服务发布TestMain
调用webservice服务log4j.properties⽇志⽂件
注意:
①:我们在访问时界⾯出现这种错误提⽰
  提⽰内容:此页⾯包含以下错误:第1列第1⾏上的错误:⽂档为空。下⾯是直到第⼀个错误的页⾯呈现
  此原因是因为我们没有在对应的实体类上添加@XmlRootElement注解导致⽆法映射为XML,从⽽导致⽂档为空
6:使⽤CXF_RS开发客户端(restful⽅式)
  我们使⽤CXF_RS开发客户端会使⽤到⼀个叫CXF的WebClient的⼯具类(后⾯章节介绍),可以发送不同类型的请求
  在编写客户端之前,我们需要把服务端的实例对象复制到客户端⾥
客户端类代码
问题:
<!--客户端加上此坐标可以转换为json数据-->
<!--服务端加上此坐标可以解析json数据-->
<!--下⾯这两个坐标不设置就会导致是发送端⽆法转换json发送,是接收端⽆法把json转换为对象接收-->
<!--设置CXF提供者坐标-->
<dependency>
<groupId>f</groupId>
<artifactId>cxf-rt-rs-extension-providers</artifactId>
<version>3.4.3</version>
</dependency>
<!--JSON转换坐标,会集成到CXF的providers⾥-->
<dependency>
<groupId&dehaus.jettison</groupId>
<artifactId>jettison</artifactId>
<version>1.4.1</version>
</dependency>
三:使⽤监控请求及响应
  file --> New SOAP Project 创建SOAP请求  file --> New REST Project 创建Rest请求(后⾯说)
四:WSDL说明书详细说明(重要)
  如果你对 XML 不熟悉的请先研究⼀下 XML ==>  学习⼀下 Schema 约束那⼀章
下⾯我就以如下的⽂件来详细分析⼀下 WSDL 说明书,这个⽂件是由我上⾯的 JAX-WS 案例⽣成的
⽰例wsdl说明书:localhost:8888/WebService/student?wsdl
⽰例wsdl类型说明书:localhost:8888/WebService/student?xsd=1
wsdl⽂档说明书是由definitions标签来包裹,内部有五⼤标签各司其职分别为
service、binding、portType、message、types
这五⼤标签我将在下⾯⼀⼀介绍
1:WSDL报⽂之  definitions
<definitions xmlns:wsu="/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wsp="/ns/ws-policy"
xmlns:wsam="/2007/05/addressing/metadata"
xmlns:soap="/wsdl/soap/"
xmlns:tns="impl.webservice.xw/"
xmlns:xsd="/2001/XMLSchema"
xmlns="/wsdl/"
targetNamespace="impl.webservice.xw/"
name="StudentWebServiceImplService">
<!--内部标签省略.....`-->
</definitions>
标签:
definitions:根元素
每个wsdl⽂件包含⼀个根元素,内部定义⼀些属性
属性:
xmlns:tns:引⽤
相当于Java⾥⾯的import包的反转路径
name:SEI定义名称
我们Java程序中的接⼝实现类,SEI定义规则是:服务接⼝类+Service后缀,Service系统⾃动追加
targetNamespace:命名空间
相当于Java⾥⾯的package,它刚好是和我们定义的的包名相反
其它属性:出现的其它属性不能改动,必须那样写,因为是整篇wsdl说明书的约束条件
2:WSDL报⽂之  types
  定义Web服务⾥⽤到的,XMLSchema定义的数据类型以外的⾃定义数据类型,对于我们⾃定义的类(Student),会对应到⼀个
<complexType>(复杂类型标签),其中⽤<element>元素指定每个参数的类型。
<types>
<xsd:schema>
<xsd:import namespace="impl.webservice.xw/"
schemaLocation="localhost:8888/WebService/student?xsd=1"/>
</xsd:schema>
</types>
标签:types
定义Web服务中⽤到的请求与响应的数据类型
标签:xsd:schema
约束标签,⽤来指定内部类型按照指定规范编写
标签:xsd:import
导⼊外部⽂件
属性:
namespace:命名空间
schemaLocation:约束⽂件地址
如下是localhost:8888/WebService/student?xsd=1约束⽂件
<xs:schema xmlns:tns="impl.webservice.xw/"
xmlns:xs="/2001/XMLSchema"
version="1.0"
targetNamespace="impl.webservice.xw/">
<!--定义countAllStudent⽅法的请求类型指定的类型是countAllStudent-->
<xs:element name="countAllStudent" type="tns:countAllStudent"/>
<!--定义countAllStudentResponse⽅法的响应类型指定的类型是countAllStudentResponse-->
<xs:element name="countAllStudentResponse" type="tns:countAllStudentResponse"/>
<!--定义findByName⽅法的请求类型指定的类型是findByName-->
<xs:element name="findByName" type="tns:findByName"/>
<!--定义findByNameResponse⽅法的响应类型指定的类型是findByNameResponse-->
<xs:element name="findByNameResponse" type="tns:findByNameResponse"/>
<!--定义⼀个复杂类型,但此类型为空(就是说countAllStudent⽅法为空参数)-->
<xs:complexType name="countAllStudent">
<xs:sequence/>
</xs:complexType>
<!--定义⼀个复杂类型,返回的是⼀个序列(参数按照要求位置)-->
<xs:complexType name="countAllStudentResponse">
<xs:sequence>
<!--此处告诉我们是⼀个响应的return参数,此时的参数类型为int 并且⾄少出现0次-->
<xs:element name="return" type="xs:int" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<!--后⾯不会的请参考具体的xml学习-->
<!--后⾯的省略........-->
</xs:schema>
3:WSDL报⽂之  message
  具体定义了在通信中使⽤的消息的数据结构,Message元素包含了⼀组Part元素,每个Part元素都是最终消息的⼀个组成部分,每个Part都会引⽤⼀个DataType(就是part⾥的element属性)来表⽰它的结构。
<message name="findByName">
<part name="parameters" element="tns:findByName"/>
<message name="findByNameResponse">
<part name="parameters" element="tns:findByNameResponse"/>
</message>
<message name="countAllStudent">
<part name="parameters" element="tns:countAllStudent"/>
</message>
<message name="countAllStudentResponse">
<part name="parameters" element="tns:countAllStudentResponse"/>
</message>
标签:message
⽤来定义请求/响应消息的结构
属性:
name:⽅法名称
标签:part
指定引⽤types中定义的标签⽚段
属性:
name:此时说明都是参数
element:引⽤指定的类型,类型在types中定义
⼤⽩话:
我们编写的SEI实现类的某⼀个⽅法会对于的两个message,分别对象请求message和响应message
⽽不管请求还是响应message都会有参数的传输,⽐如请求的message是有个请求参数的,这个请求参数
的类型就是在此处说明,并引⽤types定义的具体复杂类型
4:WSDL报⽂之  portType
  Operation是对服务中所⽀持的操作的抽象描述,⼀般单个Operation描述了⼀个访问⼊⼝的请求/响应消息对。
  PortType具体定义了⼀种服务访问⼊⼝的类型,就是输⼊/输出消息的模式及其格式。⼀个PortType可以包含若⼲个Operation,⽽⼀个Operation则是指访问⼊⼝⽀持的⼀种类型的调⽤。在WSDL⾥⾯⽀持四种访问⼊⼝调⽤的模式如单请求、单响应、请求/响应、响应/请求。  在这⾥请求指的是从客户端到Web服务端,⽽响应指的是从Web服务端到客户端。PortType的定义中会引⽤消息定义部分的⼀个到两个消息,作为请求或响应消息的格式。
<portType name="StudentWebServiceImpl">
<operation name="findByName">
<input wsam:Action="impl.webservice.xw/StudentWebServiceImpl/findByNameRequest"
message="tns:findByName"/>
<output wsam:Action="impl.webservice.xw/StudentWebServiceImpl/findByNameResponse"
message="tns:findByNameResponse"/>
</operation>
<operation name="countAllStudent">
<input wsam:Action="impl.webservice.xw/StudentWebServiceImpl/countAllStudentRequest"
message="tns:countAllStudent"/>
<output wsam:Action="impl.webservice.xw/StudentWebServiceImpl/countAllStudentResponse"
message="tns:countAllStudentResponse"/>
</operation>
</portType>
标签:portType
⽤来定义服务器端的SEI接⼝
属性:
name:定义我们的实现类名称
标签:operation
⽤来指定SEI中的处理请求的⽅法,⼀般分为请求和响应
属性:
name:SEI实现类⾥的具体实现⽅法
标签:input
指定客户端请求过来的数据,它会引⽤我们定义的message标签来强⾏约束类型
属性:
message:引⽤请求消息的约束
标签:output
指定服务端响应回去的数据,它会引⽤我们定义的message标签来强⾏约束类型
属性:
message:引⽤响应消息的约束
5:WSDL报⽂之  binding
  此标签包含了如何将抽象接⼝的元素(portType)转变为具体表⽰的细节,具体表⽰也就是指特定的数据格式和协议的结合;特定端⼝类型的具体协议和数据格式规范的绑定。JAX-RPC规范规定,SOAP绑定可以有rpc和document两种类型,分别表⽰远程过程调⽤和基于消息的⽅式。use属性可以是encoded或literal,对于前者要⽀持rpc的⽅式,对于后者要⽀持rpc和document的⽅式。
<binding name="StudentWebServiceImplPortBinding" type="tns:StudentWebServiceImpl">
<soap:binding transport="/soap/http" />
<operation name="findByName">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。