基于Apache CXF构建SOA应用基础
2014-01-17 17:06
423 查看
WebService概述
——它不是框架,更甚至不是一种技术,而是一种跨平台、跨语言的规范。WebService集中解决:
1、远程调用。
2、跨平台调用。
3、跨语言调用。
WebService在真实场景下的用途:
1、同一公司的新、旧系统的整合。
Linux上的Java应用,去调用Windows平台的Delphi应用。
2、不同公司的业务整合。
举例:在淘宝上购书,订单的查询,需要整合快递公司的系统。业务的整合就要带来不同公司的系统整合,就可能存在平台不同、语言不同的问题。
3、内容聚合
一个应用,比如需要提供,天气预报、股票行情、编程语言的排行等。这个内容聚合的应用,需要调用大量不同平台、不同语言编写的应用。
CXF概述
Axis(Apache) → Axis 2 (Apache)XFile → CXF(Celtix + XFile)
XFile (WebService框架)
Celtix (ESB框架)
SOA(面向服务的架构)
Service1,Service2,Service3 —— 所有组件都是“即插即用”的。
一般认为,面向服务体系(SOA)结构是一种软件工程方法学,同时也是一种新的软件开发范型。SOA以松散耦合的粗粒度服务为基本单元,通过开放的、标准的并独立于硬件平台、操作系统和编程语言的接口来发布服务,并且通过开放式和规范性的通信协议进行通信。SOA是一种支持多种服务方式组合、构成和跨平台、并具有一定适应性和扩展性的软件系统。
使用CXF开发WebService服务器端
注:每个WebService组件需要2个部分:接口和实现类1、开发一个WebService业务接口,该接口需要@WebService 修饰
2、开发一个WebService实现类,实现类也需要用@WebService 修饰
endpointInterface指定WebService的实现接口
3、使用Endpoint类的静态方法来发布WebService
使用CXF开发WebService客户端
1、调用CXF提供的wsdl2java工具,根据WSDL文档生成相应的Java代码WSDL— Web Service Description Language,描述了WS中有哪些操作可以调用。
任何语言实现了WebService,都需要提供、并暴露WSDL文档。
2、找到生成的wsdl2java所生成类中,一个继承了Service的类。
该类的实例可当成工厂来使用。
3、调用Service子类的实例的getXXXPort方法,返回远程WebService代理。
使用CXF处理JavaBean式的复合类型和List集合类型的形参和返回值
形参、返回值1、当形参、返回值的类型是String、基本数据类型时,CXF肯定可以轻松处理。
2、当形参、返回值类型是JavaBean式的符合类、List集合、数组等时,CXF也可以很好的处理。
3、还有一些像Map、非JavaBean式的复合类,CXF是处理不了的。
WebService核心之WSDL详解
WebService的三个技术基础:1、WSDL web service description language — web service描述语言
2、SOAP simple object access protocol — 简单对象访问协议
3、UDDI
-------------------------------------------------------------------------------------------------------
XML里的两个属性:
TargetNamespace —— 相当于Java语言里的package。
Xmlns ——相当于Java语言的import,导入一个命名空间。
-------------------------------------------------------------------------------------------------------
一次WebService的调用,其实并不是方法调用,而是发送SOAP消息(即XML文档片段)。
WebService其实是XML的应用,它和XML的关系其实是非常紧密的。
对于sayHi操作来说,
传入消息是:
<sayHi>
<arg0>字符串</arg0>
</sayHi>
传出消息是:
<sayHiResponse>
<return>字符串</return>
</sayHiResponse>
对于getCatByUser操作来说:
传入消息是:
< getCatByUser>
<arg0>
<adress>字符串</adress>
<id>整数值</id>
<name>字符串</name>
<pass>字符串</pass>
</arg0>
</getCatByUser>
传出消息是:
< getCatByUserResponse>
<return> ——可出现0~N次
<color>字符串</color>
<id>整数值</id>
<name>字符串</name>
</return>
</getCatByUserResponse>
WSDL深入详解和WebService调用过程的底层本质
通俗地说,WSDL文档描述了Web Service如下3个方面:— What:该Web Service包含了“什么”操作。
— How :该Web Service的操作应该“怎样”调用?
— Where:该Web Service的服务地址。
调用一次Web Service的本质:
1. 客户端把调用方法的参数,转换生成XML文档片段(SOAP消息,input消息)。
——该文档片段必须符合WSDL定义的格式
2. 通过网络,把XML文档片段传给服务器。
3. 服务器接收到XML文档片段。
4. 服务器解析XML文档片段,提取其中的数据。
并把这些数据转换成调用WebService所需要的参数。
5. 服务器执行方法。
6. 把执行方法得到的返回值,再次转换生成为XML文档片段(SOAP消息,output消息)。
——该文档片段(消息)必须符合WSDL定义的格式
7. 通过网络,把XML文档片段传给客户端。
8. 客户端接收到XML文档片段。
9. 客户端解析XML文档片段,提取其中的数据。
并把这些数据转换成调用WebService的返回值。
注:只要得到WebService的WSDL文档,接下来程序就可以调用Web Service
从上面的调用本质来看,要一个语言支持Web Service,唯一的要求是:该语言支持XML文档解析、生成、支持网络传输。
处理Map等CXF无法自动转换的复合数据类型的形参和返回值
在CXF开发中,如果遇到CXF无法自动处理的类型,就需要程序员自行处理。处理思路是:提供一个转换器,该转换器负责把CXF搞不定的类型,转换成CXF搞得定的类型。
1、使用@XmlJavaTypeAdapter修饰CXF无法自动处理的类型。
注意:不是修饰这个方法,而是修饰这个搞不定的类型。
使用该Annotation时,通过Value属性指定一个转换器。这个转换器应该是一个XMLadapter类
2、实现自己的转换器,此时需要开发一个CXF搞得定的类型。
对于getAllCats操作来说:
传入消息是:
< getAllCats>
</getAllCats>
传出消息是:
< getAllCatsResponse>
<return>
<entries> ——可出现0~N次
<key>字符串</key>
<value>
<color>字符串</color>
<id>整数值</id>
<name>字符串</name>
<v/alue>
</entries>
</return>
</getAllCatsResponse>
CXF拦截器的理论以及如何为CXF的客户端和服务端添加拦截器
WebService的调用本质:1. 客户端把需要调用的参数,转换成XML文档片段(SOAP消息,input)。
2. 客户端通过网络把XML文档片段传给远程服务器。
3. 服务器接收XML文档片段。
4. 服务器解析XML文档片段,提取其中的数据,并把数据转化为调用所需的参数。
5. 服务器执行方法。
6. 得到方法的返回值,服务器把方法的返回值转换为XML文档片段(SOAP消息,output)。
7. 服务器通过网络把XML文档片段传给远程客户端。
8. 客户端接收XML文档片段。
9. 客户端解析XML文档片段,提取其中的数据,并把数据转化为返回值。
Web Service的三个技术基础:
——WSDL:
Web Service接口
1.Types(标准的Schema)
2.2N的Message
3.PortType —— N个operation子元素
——SOAP:
Header : Header元素是可选的,由程序员控制添加。
Body: Body元素是默认的,
Body元素可有两种情况,
当WebService交互正确时,Body元素的内容由WSDL控制。
当WebService交互出错时,Body元素的内容将是Fault子元素。
——UDDI
Web Service急需解决的问题:如何进行权限控制?
解决思路是:服务器要求input消息总是携带用户名、密码信息。——如果没有用户名、密码信息,直接拒绝调用。
如果不用CXF等框架,SOAP消息的生成、解析都是由程序员负责。
无论是添加用户名、密码信息,还是提取用户名、密码信息,都可由程序员的代码完成。
如果用CXF等框架,SOAP消息的生成、解析是由CXF等框架来完成。
*****************************************************************
拦截器
为了让程序员能访问、并修改CXF框架所生成的SOAP消息,CXF提供了拦截器。
服务器端添加拦截器
1. 获取Endpoint的publish方法返回值。
2. 调用该方法的返回值的getInInterceptor、getOutInterceptor方法来获取In、Out拦截器列表,接下来就可以添加拦截器了。
客户端添加拦截器
1. 调用ClientProxy的getClient方法,调用该方法以远程Web Service的代理为参数。
Client client = ClientProxy.getClient(hw);
2. 调用Client的对象的getInInterceptor、getOutInterceptor方法来获取In、Out拦截器列表,接下来就可以添加拦截器了。
Client.getInInterceptors().add(newLoggingInInterceptor());
Client.getOutInterceptors().add(newLoggingOutInterceptor ());
WebService核心技术之SOAP协议深入详解
对于sayHi操作:传入消息
Payload: <?xmlversion="1.0" ?>
<S:Envelopexmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:sayHixmlns:ns2="http://ws.cxf.fkjava.org/">
<arg0>孙悟空</arg0>
</ns2:sayHi>
</S:Body>
</S:Envelope>
--------------------------------------
传出消息
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:sayHiResponsexmlns:ns2="http://ws.cxf.fkjava.org/">
<return>孙悟空,您好现在时间是:Sun Jan 12 15:02:26 CST 2014</return>
</ns2:sayHiResponse>
</soap:Body>
</soap:Envelope>
----------------
对于getAllCats操作:
传入消息:
-------------
Payload: <?xmlversion="1.0" ?>
<S:Envelopexmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getAllCatsxmlns:ns2="http://ws.cxf.fkjava.org/"/>
</S:Body>
</S:Envelope>
-----------
传出消息:
-------------
Payload: <soap:Envelopexmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:getAllCatsResponsexmlns:ns2="http://ws.cxf.fkjava.org/">
<return>
<entries>
<key>第4个</key>
<value>
<color>黑白色</color>
<id>4</id>
<name>熊猫</name>
</value>
</entries>
<entries>
<key>第3个</key>
<value>
<color>粉色</color><id>3</id><name>kitty</name>
</value>
</entries>
<entries><key>第1个</key><value><color>橙色</color><id>1</id><name>garfield</name></value>
</entries>
<entries><key>第2个</key><value><color>蓝色</color><id>2</id><name>机器猫</name></value>
</entries>
</return>
</ns2:getAllCatsResponse>
</soap:Body>
</soap:Envelope>
-------------
为CXF服务器端添加自定义拦截器进行权限检查
自定义拦截器:需要实现Intercptor接口。实际上,我们一般会继承AbstractPhaseInterceptor。在ServerMain.java中添加In 拦截器,该AuthInterceptor就会负责检查用户名、密码是否正确。
为CXF客户端添加自定义拦截器完成权限控制。
复制Auth_Client,在ClientMain里添加Out拦截器,AddHeaderInceptorclient.getOutInterceptors().add(newAddHeaderInceptor(“fkjava”,”1222”));
AddHeaderInceptor放在org.crazyit.cxf.ws.auth包里,继承AbstractPhaseInterceptor类,范型是 SoapMessage
Payload: <soap:Envelopexmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<authHeader>
<userId>fkjava</userId>
<userPass>1222</userPass>
</authHeader>
</soap:Header>
<soap:Body>
<ns2:sayHi xmlns:ns2="http://ws.cxf.fkjava.org/">
<arg0>孙悟空</arg0>
</ns2:sayHi>
</soap:Body>
</soap:Envelope>
--------------
相关文章推荐
- java : [基于Apache CXF构建SOA应用] 书中提到的 common_build.xml
- 互联网基础应用架构构建(基于docker)
- 基于云存储服务构建应用的基础架构(图)
- 基于SOA构建随需应变的企业应用
- 基于SOA构建随需应变的企业应用
- 快速构建Windows 8风格应用18-基础控件I
- LinuxC/C++编程基础(2) 基于boost::any构建数据容器
- Extraction应用构建平台应用基础(五)------组织架构篇
- Spring实战5-基于Spring构建Web应用
- 使用Gradle构建基于Groovy语言的经典Java EE应用
- 将AspectJ集成到基于Eclipse + Lomboz + XmlBuddy的Web应用中去 - 基础篇
- 将 Shiro 作为应用的权限基础 二:基于SpringMVC实现的认证过程
- 构建基于LBS的大数据应用
- 重新整理后的Oracle OAF学习笔记——4.应用构建基础之实现视图
- 微服务应用-基于Spring Cloud和Docker构建电影推荐微服务
- Windows Server 2012活动目录基础配置与应用(新手教程)之10---基于组策略的软件部署
- 基于dropwizard/metrics ,kafka,zabbix构建应用统计数据收集展示系统
- 基于C#的MongoDB数据库开发应用(1)--MongoDB数据库的基础知识和使用
- 微服务应用-基于Spring Cloud和Reactor构建网上商店微服务(上)
- [Android] 基于 Linux 命令行构建 Android 应用(六):Android 应用签名