========================第一讲=======================
WebService概述
=====================================================
Web Service 不是框架,更甚至不是一种技术,而是一种跨平台,跨语言的规范。
Web Service实际用途:
1.同一公司的新,旧系统的整合。
2.不同公司的业务整合。
3.内容聚合。
CXF
Axis(Apache) --> Axis2(Apache)
XFire --> CXF(XFire + Celtrix)
XFire (Web Service框架)
Celtrix (ESB框架)
SOA(面向服务的架构)
--所有组件都是即插即用
1.各种提供服务的组件。(Web Service)
2.企业服务总线(Enterprise Service Bus ,ESB)
CXF号称SOA框架
CXF 内置了一个Jetty Web服务器
======================第二讲/第三讲======================
使用CXF开发WebService服务器端和客户端
=========================================================
用CXF开发Web Service 服务器端:
/****************
每个WebService组件需要两个组件:接口和实现类
****************/
1)开发一个Web Service 业务接口,接口用@WebService修饰
2)开发一个Web Service 实现类,接口用@WebService修饰
@WebService(endpointInterface="com.lr.HelloWorld",ServiceName="MyServiceName")
3)发布WebService
--------------------------------------------
用CXF开发Web Service客户端:
1)用CXF提供的wsdl2java工具,根据WSDL文档生成相应的java代码
WSDL-Web Service Definition Language
任何语言实现了Web Service ,都需要提供并暴露WSDL文档
wsdl2java http://192.168.10.254/fkjava?wsdl
2)找到wsdl2java所生成类中,一个继承了Service的类。
该类的实例可当成工厂类使用。
3)调用Service子类的实例的getXXXPort方法,返回远程Web Service的代理()。
=========================第四讲===========================
使用CXF处理JavaBean式复合类型和List集合类型的形参和返回值
==========================================================
形参/返回值
1)当形参/返回值的类型是String、基本数据类型时,可以轻松处理;
2)当形参/返回值类型是javabean式的复合类、List集合、数组等时;
在实际的项目中,Web Service组件并不会自己实现业务功能,他只是调用业务逻辑组件的方法来暴露Web Service
wsdl2java生成的javabean没有含参数的构造器,javabean 应该实现equals方法以便在List中查找
========================第五讲/第六讲=======================
WebService核心
============================================================
/********************************
XML里的两个属性:
targetNamespace - 相当于java中的package
不同的命名空间在不同的文件中
xmlns- 相当于java中的import
xmlns="targetNamespace"
xmlns:p = "targetNamespace" p是代号可以随便写,以便使用
********************************/
Web Service 三大基础
1.WSDL : Web Service Defination Language Web Service 定义语言)
通俗地说,WSDL文档描述了WebService如下3个方面:
-WHAT:该WebService包含什么操作
-HOW:该WebService的操作应该怎么调用
-WHERE:该WebService的服务地址
/*******************************
只要得到Web Service的WSDL文档,接下来程序就可以调用Web Service
*******************************/
-------------------------------------------
Web Service 接口
-types(标准的Schema)
-message(2N个)
-portType(N个operation)
Web Service实现
-binding (N个更详细的operation)
-service (指定Web Service的服务器名称/地址)
-------------------------------------------
一次WebService的调用--其实并不是方法调用,而是发送SOAP消息(即XML片段);
调用一次Web Service 的本质:
1.客户端把调用方法参数,转化为XML文档片段(SOAP消息)--该文档片段必须符合WSDL定义的格式;
2.通过网络把XML文档片段传给服务器;
3.服务器接收到XML文档片段;
4.服务器解析XML文档片段,提取其中的数据,并把数据转换成调用Web Service所需的参数值;
5.服务器端执行方法;
6.把执行方法得到的返回值再次转换生成XML文档片段(SOAP消息)--该文档片段必须符合WSDL定义的格式;
7.通过网络把XML文档片段传给客户端;
8.客户端接收到XML文档片段;
9.客户端解析XML文档片段,提取其中的数据,并把数据转换调用Web Service的返回值;
从上面调用本质来看,要一个语言支持Web Service,唯一的要求是:该语言支持XML文档解析、生成,支持网络传输。
2.SAOP:Simple Object Access Protocol(简单对象访问协议)
=========================第七讲=============================
处理Map等CXF无法自动转换的复合数据类型的形参和返回值
==========================================================
在CXF开发中,如果遇到系统无法自动处理的类型,就需要这样处理
思路:提供一个转换器(继承XmlAdapter),负责把CXF无法自动处理的类型,转换为可以处理的类型。
1.使用@XmlJavaTypeAdapter注释修饰CXF无法自动处理的类型;
使用该Annotation处理的时候,需要指定一个转换器
2.实现自己的转换器,需要开发一个CXF可以处理的类型;
==========================第八讲/第十讲========================
CXF拦截器
===========================================================
Web Service 急需解决的问题:如何进行权限控制?
思路:服务器端要求input消息携带用户名密码信息,否则拒绝调用。
如果不用CXF等框架,SOAP消息的生成、解析都是由程序员负责的,因此无论是添加用户名密码信息,还是提取用户名密码信息,都可以由程序员的代码完成。
如果用CXF等框架,SOAP消息的生成、解析都是由CXF等框架来完成的。
为了让程序员能访问、修改CXF框架所生成的XML(SOAP消息),CXF提供了拦截器。
**服务器端添加拦截器
1.获取Endpoint的publish方法返回值;
2.调用该方法返回值的getInInterceptors()、getOutInterceptors()方法获取In、Out拦截器列表,添加拦截器;
//调用Endpoint的publish方法发布Web Service
EndpointImpl ep =EndPoint.publish("http://10.1.14.6");
//添加In拦截器
ep.getInInterceptors().add(e);
//添加Out拦截器
ep.getOutInterceptors().add(e);
**客户端添加拦截器
1.调用ClientProxy的getClient方法,调用该方法以远程WebService的代理为参数;
2.调用Client对象的getInInterceptors()、getOutInterceptors()方法获取In、Out拦截器列表,添加拦截器;
HelloWorldWs factory =newHelloWorldWs();
//此处返回的是远程WebService的代理
HelloWorld hw = factory.getHelloWorldPort();
Client client =ClientProxy.getClient(hw);
client.getInInterceptors().add(e);
client.getOutInterceptors().add(e);
**自定义拦截器:
需要实现Interceptor接口,实际上,一般会继承AbstractPhaseInterceptor
CXF已经实现了一些拦截器但是API文档中未提及;
// 服务器添加校验Header拦截器
//通过PhaseInterceport,可以指定拦截器在哪个阶段起作用
publicclassAuthInterceptorextendsAbstractPhaseInterceptor<SoapMessage>{
publicAuthInterceptor(){
//该拦截器会在“调用之前”拦截;Phase是阶段常量
super(Phase.PRE_INVOKE);
}
//实现自己的拦截器时,需要实现handleMessage方法
//handleMessage方法中的形参就是被拦截到的SOAP消息
//一旦程序获取到SOAP消息,就可以解析或修改SOAP消息
@Override
publicvoid handleMessage(SoapMessage msg)throwFault{
//得到SOAP消息的所有Header
List<Header> headers = msg.getHeaders();
}
}
//客户端添加Header消息拦截器
publicclassAddHeaderInterceptorextendsAbstractPhaseInterceptor<SoapMessage>{
privateString userId;
privateString userPass;
publicAddHeaderInterceptor(String userId,String userPass){
super(Phase.PREPAR_SEND);//准备发送时调用
this.userId = userId;
this.userPass = userPass;
}
@Override
publicvoid handleMessage(SoapMessage msg)throwsFault{
List<Header> headers = msg.getHeaders();
//把ele元素包装成Header,并添加到SOAP消息的Header列表
headers.add(newHeader(newQName("fkjava"),ele));
}
}
====================第九讲/第十讲/第十一讲=====================
Web Service核心之SOAP协议详解
========================================================
在服务器端添加In/Out日志拦截器,从日志分析;
SOAP
Header 可选的,有程序员控制添加;
Body Body元素总是默认的,Body元素里可有两种情况
-当Web Service交互正确时,Body元素里的内容由WSDL控制;
-当Web Service交互出错时,Body元素内容是Fault
===========================第十二讲/第十三讲========================
CXF与Spring整合
==============================================================
可以在传统的Java EE应用的基础上添加一层Web Service。
我们的Java EE应用就可以对外暴露成Web Service,这样就允许任何平台任何语言编写的程序来调用这个Java EE应用。
在传统SSH项目基础上增加WebService的步骤
1.复制CXF的Jar包;(最核心6个)
2.在web.xml配置CXF的核心控制器:CXFServlet;
3.在Spring配置文件中倒入CXF提供Schema,XML配置文件;
4.在Spring配置文件中使用jaxws:endpoint元素暴露WebService;
5.如果要添加拦截器,在jaxws:endpoint元素里添加inInterceptors,outInterceptors子元素;
**implementor指定WebService的服务提供者。支持两种方式:
a.直接给定服务器提供者的类名(不推荐);
<javws:endpoint implementor="org.lr.cxf.ws.impl.HelloWorldWs" address="/lrservice">
</javws:endpoint>
b.设置为容器中一个bean.
<bean id="helloWorldWs" class="org.lr.cxf.ws.impl.HelloWorldWs" p:us-ref="userService"/>
<!-- id前要加# -->
<javws:endpoint implementor="#helloWorldWs" address="/lrservice">
</javws:endpoint>
===========================第十四讲=============================
CXF与Spring整合的第二种方式_让JavaEE应用依赖第三方WebService--就是调用WebService
==============================================================
1.复制CXF的Jar包;(最核心6个)
2.在web.xml配置CXF的核心控制器:CXFServlet;
3.在Spring配置文件中倒入CXF提供Schema,XML配置文件;
4.在Spring配置文件中使用jaxws:client元素调用WebService;
5.如果要添加拦截器,在jaxws:client元素里添加inInterceptors,outInterceptors子元素;
**为了保证该Web Service代理对象可以自动装配给Action,应该保证该id属性值与Action中setter方法名有对应关系
<jaxws:client id="hw" serviceClass="org.lr.cxf.ws.HelloWorld" address="http://192.168.10.254:9999/lrservice"></jaxws:client>