您的位置:首页 > 运维架构 > Apache

基于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拦截器,AddHeaderInceptor

client.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>
--------------



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: