cxf笔记记录
一、Web Service框架介绍:
1. WebService框架的作用:
-- WebService只是一种思想,不是一个具体的框架.
-- 它也是javaEE的规范。
-- 它可以跨平台(操作平台、应用平台)、跨语言的应用之间的远程调用.
2. WebService框架的应用场景:
-- 不同公司业务整合
不同公司业务整合,主要就是业务平台的整合,
有可能出现运行平台不一样,开发语言不一样.
-- 同一个公司新、旧系统的整合.
3. WebService与SOA:
SOA:Service Oriented Architecture 面向服务架构,
一个软件由N个服务组件以完全解耦的方式组合在一起,
组件与组件之间通过ESB(企业服务总线)进行通信。
它是目前较热门的技术,由ESB与Web Service技术组成。
Enterprise Service Bus:ESB
4. Web Service与云服务:
云服务:更多是一种商业模式,
对于云时代电脑而言,所有的数据计算、存储、程序…都交给网络的“云”完成,
而“云”则由云服务商提供。
按照云计算的理念:所有用户应该按需付费(就像用水、用电一样)。
当云服务商对外提供服务给客户调用时,
云服务商一定会采用一种跨平台、跨语言的技术来提供“云服务”,
此时Web Service也是一个极佳的选择。
二、Web Service实现商
Axis --> Axis2
XFire + Celtix(ESB) SOA
CXF 2.6.16
三、CXF下载与安装
-- 它的官方网站: http://cxf.apache.org
-- apache-cxf-2.6.16.zip
v2.xx.xx(所有模块分别打成了jar包,有总的jar包)
v3.xx.xx(所有模块分别打成了jar包,没有总的jar包)
解压:
-- bin:存放了命令
-- docs: api文档
-- lib: 存放了自己的jar与第三方的jar.
-- modules : 所有模块
-- samples : 示例
安装:
-- 把bin目录添加到环境变量
四、CXF入门
1.开发Web Service 服务端来暴露服务组件
步骤:
a. 拷贝jar包(7个jar) required文件夹
如果是普通的java项目还需要jetty的jar包
b. 开发WS服务组件
WS服务组件 = WS服务接口 + WS服务接口实现类
WS服务接口: @WebService()
WS服务接口实现类: @WebService()
@WebService(endpointInterface="cn.itcast.ws.AdminService",
serviceName="TestService")
c. 暴露Web Service服务组件
Endpoint.publish("访问地址", "服务组件对象");
http://192.168.26.10:8888/itcast?wsdl (Web Service的xml描述文档)
2.开发客户端来调用Web Service服务组件.
满足条件:必须要有服务端提供的wsdl文档访问地址.
http://192.168.26.10:8888/itcast?wsdl (外网访问)
步骤:
a. 生成客户端代码的两种方式:
第一种方式(用CXF框架自带的命令):
-- 用wsdl2java命令生成客户端代码
-- wsdl2java wsdl访问URL
wsdl2java http://192.168.26.10:8888/itcast?wsdl
第二种方式(用java自带的命令):
-- 用wsimport命令生成客户端代码
-- wsimport wsdl访问URL
wsimport http://192.168.26.10:8888/itcast?wsdl -keep (保留源代码)
b. 在生成的多个java类中找到Service子类,用它来创建WebService服务工厂.
调用getXxxxPort()方法获取远程WebService服务组件的代理对象.
再调用服务组件中的方法即可.
五、WebService服务组件中的操作的数据类型(方法的形参与返回值)
1. CXF能处理的数据类型
-- java的8个基本数据类型、包装类、String
-- javaBean式的复合类
-- List集合、Set集合、Map集合(客户端调用比较麻烦)
2.CXF不能处理的数据类型
-- 非javaBean式的复合类 (File)
xml与java中的数据类型转换器
-- @XmlJavaTypeAdapter
-- 自定义类型转换器需要继承XmlAdapter
XmlAdapter<ValueType,BoundType>
ValueType: JAXB它知道处理的类型
BoundType: JAXB它不知道处理的类型
JAXB : Java Xml Binding 它也是javaEE的规范,
它规定了java中的数据类型与xml中数据类型怎样转换
注意:在类型转换时,数据不能丢失.
不能处理的数据类型:File
目标:把file这种数据类型转换成cxf能够处理的数据类型.
-- 接收客户端调用的参数,转化成服务端能处理类型
-- 服务端返回给客户端的数据类型,转化成客户端能处理类型
@XmlJavaTypeAdapter指定转来转去的类型适匹器
六、WSDL详解
Web Service三大技术基础:
-WSDL:Web Service Description Language, Web Service描述语言。
-SOAP:Simple Object Access Protocol简单对象访问协议,Web Service的通信协议。
-UDDI:Universal Description Discovery and Integration统一描述、
发现、整合,服务组件注册中心(名存实亡)。
WSDL文档分两个部分:
a.接口部分
(http://192.168.26.10:8888/itcast?wsdl=AdminService.wsdl)
1. <wsdl:types ../> 类型元素
-- <xs:schema .../> 它是一份标准的约束文档.
-- <xs:complexType ../>每一个复杂类型都会生成一个java类
2. N个<wsdl:message .../> 对应操作中的输入与输出消息
3. <wsdl:portType .../>
-- <wsdl:operation name="方法名" ../> 跟ws服务接口的方法一样多
操作中子元input与output子素用来定义输入参数与输出值
b.实现类部分
(http://192.168.26.10:8888/itcast?wsdl)
1. <wsdl:binding .../>
-- <soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
style: 底层传输风格(xml文档的方式)
transport: 底层传输协议
2. <wsdl:service name="TestService"/> name指定生成的服务类名
<wsdl:port binding="tns:TestServiceSoapBinding"
name="AdminServiceImplPort">
<soap:address location="http://192.168.26.10:8888/itcast"/>
</wsdl:port>
-- soap:address指定访问地址
以login操作为示例
-- 发送xml片断
<login>
<arg0>admin</arg0>
<arg1>123456</arg1>
</login>
-- 接收xml片断
<loginResponse>
<return>登录成功!</return>
</loginResponse>
一次Web Service调用的完整过程:
1.客户端将调用参数转换成XML片段。
2. 客户端将XML片段通过网络发送给服务端。
3. 服务端接收XML片段。
4. 服务端解析XML片段,提取其中数据,并转换相应的调用参数。
5. 服务端执行方法,得到返回值。
6. 服务端将返回值转换成XML片段。
7. 服务端将XML片段通过网络发送给客户端。
8. 客户端接收XML片段。
9. 客户端解析XML片段,提取其中数据,转换成调用WS的返回值。
说明:通过上面描述可以发现,一个语言要支持Web Service,只要满足如下2个要求:
- 支持XML的解析、生成。
- 支持网络通信
tomcat: web服务器, apache 它的作者是javaEE web规范的制订者
jetty: web服务器,codehuas-->eclipse. 它并不比tomcat差,有些方面比tomcat还好
作为嵌入服务器。
七、拦截器
因为用了CXF这个框架,程序员不需要自己封装发出的xml片断,
也不需要解析接收到的xml片断,如果需要查看xml片断或修改xml片断,
就需用拦截器.soap包(xml片断)
1. 在服务端添加拦截器查看SOAP包
操作步骤:
a. 获取EndpointImpl对象
EndpointImpl endpointImpl = (EndpointImpl)Endpoint.publish(address, userService);
b. 获取所有的in拦截器集合
List<Interceptor<?>> inLists = endpointImpl.getInInterceptors();
c. 获取所有的out拦截器集合
List<Interceptor<?>> outLists = endpointImpl.getOutInterceptors();
d. 添加自己的in拦截器与out拦截器.
inLists.add(new LoggingInInterceptor());
outLists.add(new LoggingOutInterceptor());
服务端接收到的soap包:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:login xmlns:ns2="http://ws.itcast.cn/">
<arg0>admin</arg0>
<arg1>99999</arg1>
</ns2:login>
</S:Body>
</S:Envelope>
服务端发送出去的soap包:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:loginResponse xmlns:ns2="http://ws.itcast.cn/">
<return>admin,登录成功!</return>
</ns2:loginResponse>
</soap:Body>
</soap:Envelope>
soap包格式:
<Envelope>
<Header> -- 可有可无,程序员自己制订,一般存放鉴权信息
</Header>
<Body> -- 必须要有的元素,程序不能修改,因为body部分需要遵守SOAP协议.
--交互正常,body子元素部分遵守SOAP协议,由CXF框架自己生成
--交互出错, 包含<soap:Fault>子元素,该子元素中有错误代号与错识原因
</Body>
</Envelope>
2. 在客户端添加拦截器查看SOAP包(拷贝7个jar包)
操作步骤:
a. 获取Client对象
Client client = ClientProxy.getClient(服务对象);
b. 获取所有的in拦截器集合
List<Interceptor<?>> inLists = client.getInInterceptors();
c. 获取所有的out拦截器集合
List<Interceptor<?>> outLists = client.getOutInterceptors();
d. 添加自己的in拦截器与out拦截器.
inLists.add(new LoggingInInterceptor());
outLists.add(new LoggingOutInterceptor());
3.做权限拦截.
-- 思路:需要在soap包中添加一个header元素,用来携带鉴权信息.
header元素中的子元素应该由服务端来约定. 客户端要遵守服务端的约定.
在发出soap包时需要在header元素中添加服务端约定的子元素.
a.服务端制订heaer头的约定:
<header>
<auth>
<auth_id>admin</aut_id>
<auth_pwd>888888</auth_pwd>
</auth>
</header>
服务端需要添加In拦截器,拦截收到得soap包信息,解析header头,进行权限验证.
-- 需要自定义自己In拦截器. 继承AbstactPhareInterceptor
b.客户端在发送soap包之前,添加header头.
客户端需要添加Out拦截器,拦截将要发送的soap包, 添加header头.
八、ssh + cxf 做服务端
1. 拷贝jar包
(spring4、struts2、hibernate5、mysql、jstl、struts2-spring-plugin).
2. Spring4与Struts2整合
-- web.xml
-- /WEB-INF/applicationContext.xml (spring)
-- src/struts.xml (struts2)
3. Spring4与Hibernate5整合
-- /WEB-INF/applicationContext.xml
dataSource、SessionFactory、TransactionManager、声明式事务配置、事务切面
4. 分包 common、cxf、dao、domain、service
5. Spring4与cxf整合
步骤:
-- 拷贝jar (7个jar)
-- 需要在web.xml文件中配置它的核心CXFServlet. (java_first_spring_support示例)
<!-- 配置CXF框架核心的CXFServlet -->
<servlet>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
-- 提供cxf与Spring4整合的配置文件
/WEB-INF/applicationContext-cxf.xml
a. 要引用jaxws这个命名空间.
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
b. 导入cxf整合spring的一份配置文件
<!-- 导入CXF整合Spring4的配置文件 -->
<import resource="classpath:META-INF/cxf/cxf.xml"/>
-- 提供Web Service服务
<!-- 配置提供Web Service服务
http://localhost:8080/sshcxf_server/services/fkit
-->
<jaxws:endpoint implementor="#adminService" address="/fkit">
<!-- 配置In拦截器 -->
<jaxws:inInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
<bean class="org.fkjava.sshcxf.cxf.interceptor.AuthInterceptor"/>
</jaxws:inInterceptors>
<!-- 配置Out拦截器 -->
<jaxws:outInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
</jaxws:outInterceptors>
</jaxws:endpoint>
九、ssh + cxf 做客户端
(调用第三方的Web Service服务)
Spring4与cxf整合
步骤:
-- 拷贝jar (7个jar)
-- 提供cxf与Spring4整合的配置文件
/WEB-INF/applicationContext-cxf.xml
a. 要引用jaxws这个命名空间.
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
b. 导入cxf整合spring的一份配置文件
<!-- 导入CXF整合Spring4的配置文件 -->
<import resource="classpath:META-INF/cxf/cxf.xml"/>
-- 开发调用第三方Web Service服务的客户端:
欢迎关注