CXF开发实例.docx
《CXF开发实例.docx》由会员分享,可在线阅读,更多相关《CXF开发实例.docx(39页珍藏版)》请在冰豆网上搜索。
CXF开发实例
一、CXFWebService准备工作
二、CXF入门示例
三、CXF对Interceptor拦截器的支持
四、CXFWebService中传递复杂类型对象
五、CXF整合Spring
Version1.02011-03-30
zx
授之以鱼,不如授之以渔!
希望能给广大IT朋友带来一些帮助
IT达人
自由IT职业
506637315
2011-3-15
CXFWebService
上次介绍了Axis的WebService,现在我们来看看CXF是怎么完成WebService的。
Axis1WebService在线博文:
Axis2WebService在线博文:
一、准备工作
1、CXF官方网址:
http:
//cxf.apache.org/
2、Jar包下载地址:
http:
//www.apache.org/dyn/closer.cgi?
path=/cxf/2.3.3/apache-cxf-2.3.3.zip
将下来的jar包解压后,目录大概就这样
bin目录提供的是常用的dos控制台命令工具
docs帮助文档
libjar包、依赖库
lib-samples也是jar包,有jetty、httpclients、junit等jar包
modules打包好的WebService模块
samples示例demo
3、源码下载:
http:
//www.apache.org/dyn/closer.cgi?
path=/cxf/2.3.3/apache-cxf-2.3.3-src.zip
有时候你可以看看源码,对你了解和学习CXFWebService都会有作用。
4、CXF的特性
有代码生成工具:
JavatoWSDL;WSDLtoJava;XSDtoWSDL;WSDLtoXML;WSDLtoSOAP;WSDLtoService;
支持JAX-WS、JAX-WSA、JSR-181和SAAJ;支持SOAP1.1、1.2、WS-IBasicProfile、WS-Security、WS-Addressing、WS-RM和WS-Policy;支持WSDL1.1、2.0;支持MTOM;、JavaScript、通过Yoko支持CORBA;通过Tuscany支持SCA;通过ServiceMix支持JBI
内置Jetty应用服务器
二、CXF入门实例
又一HelloWorld示例,老套的HelloWorld是入门经典。
也是基础和必须掌握的,下面看看HelloWorldWebService,很简单。
需要的jar包如下:
1、HelloWorldService服务器端代码
packagecom.hoo.service;
importjavax.jws.WebParam;
importjavax.jws.WebService;
importjavax.jws.soap.SOAPBinding;
importjavax.jws.soap.SOAPBinding.Style;
/**
*function:
CXFWebService服务器端helloWorld示例
*@authorhoojo
*@createDate2011-3-16上午08:
29:
07
*@fileHelloWorld.java
*@packagecom.hoo.service
*@projectCXFWebService
*@blog
*@emailhoojo_@
*@version1.0
*/
@WebService
@SOAPBinding(style=Style.RPC)
publicclassHelloWorldService{
publicStringsayHello(@WebParam(name="name")Stringname){
returnname+"say:
HelloWorld";
}
}
要说明的是,上面的服务器端代码运用了JDK5的新特性Annotation,这个非常好用。
需要注意的是,如果不添加@SOAPBinding(style=Style.RPC)注解,将会出现异常:
com.sun.xml.internal.ws.model.RuntimeModelerException:
runtimemodelererror
还有就是如果jdk版本在1.6下,也会出现上面的异常。
解决办法有:
1>先用apt命令将主程序进行编译,然后生成一些java文件
2>升级JDK到版本jdk1.6u17或以后
2、发布HelloWorldService,代码如下:
packagecom.hoo.service.deploy;
importjavax.xml.ws.Endpoint;
importcom.hoo.service.HelloWorldService;
/**
*function:
发布CXFWebService
*@authorhoojo
*@createDate2011-3-17上午09:
24:
33
*@fileDeployHelloWorldService.java
*@packagecom.hoo.deploy
*@projectCXFWebService
*@blog
*@emailhoojo_@
*@version1.0
*/
publicclassDeployHelloWorldService{
/**
*function:
发布WebService
*@authorhoojo
*/
publicstaticvoiddeployService(){
System.out.println("Serverstart……");
HelloWorldServiceservice=newHelloWorldService();
Stringaddress="http:
//localhost:
9000/helloWorld";
Endpoint.publish(address,service);
}
publicstaticvoidmain(String[]args)throwsInterruptedException{
//发布WebService
deployService();
System.out.println("serverready……");
Thread.sleep(1000*60);
System.out.println("serverexiting");
//休眠60秒后就退出
System.exit(0);
}
}
运行上面的main函数后,如果没有发现异常。
基本信息是这样的:
Serverstart……
2011-3-1710:
17:
25org.apache.cxf.service.factory.ReflectionServiceFactoryBeanbuildServiceFromClass
信息:
CreatingService{fromclasscom.hoo.service.HelloWorldService
2011-3-1710:
17:
25org.apache.cxf.endpoint.ServerImplinitDestination
信息:
Settingtheserver'spublishaddresstobehttp:
//localhost:
9000/helloWorld
2011-03-1710:
17:
25.375:
INFO:
:
jetty-7.2.2.v20101205
2011-03-1710:
17:
25.468:
INFO:
:
StartedSelectChannelConnector@localhost:
9000
serverready……
那么你在WebBrowser中请求:
http:
//localhost:
9000/helloWorld?
wsdl就可以看到xml内容了。
3、定制客户端调用WebService的接口,这个接口中的方法签名和参数信息可以从wsdl中的内容看到,代码如下:
packagecom.hoo.service;
importjavax.jws.WebParam;
importjavax.jws.WebService;
/**
*function:
客户端调用WebService所需要的接口
*@authorhoojo
*@createDate2011-3-17上午09:
00:
00
*@fileIHelloWorldService.java
*@packagecom.hoo.service
*@projectCXFWebService
*@blog
*@emailhoojo_@
*@version1.0
*/
@WebService
publicinterfaceIHelloWorldService{
publicStringsayHello(@WebParam(name="name")Stringname);
}
4、编写客户端调用WebService代码
packagecom.hoo.client;
importorg.apache.cxf.jaxws.JaxWsProxyFactoryBean;
importcom.hoo.service.IHelloWorldService;
/**
*function:
CXFWebService客户端调用代码
*@authorhoojo
*@createDate2011-3-16上午09:
03:
49
*@fileHelloWorldServiceClient.java
*@packagecom.hoo.client
*@projectCXFWebService
*@blog
*@emailhoojo_@
*@version1.0
*/
publicclassHelloWorldServiceClient{
publicstaticvoidmain(String[]args){
//调用WebService
JaxWsProxyFactoryBeanfactory=newJaxWsProxyFactoryBean();
factory.setServiceClass(IHelloWorldService.class);
factory.setAddress("http:
//localhost:
9000/helloWorld");
IHelloWorldServiceservice=(IHelloWorldService)factory.create();
System.out.println("[result]"+service.sayHello("hoojo"));
}
}
运行上面的程序后,结果如下:
2011-3-1710:
23:
34org.apache.cxf.service.factory.ReflectionServiceFactoryBeanbuildServiceFromClass
信息:
CreatingService{fromclasscom.hoo.service.IHelloWorldService
[result]hoojosay:
HelloWorld
三、CXF对Interceptor拦截器的支持
前面在Axis中介绍过Axis的Handler,这里CXF的Interceptor就和Handler的功能类似。
在每个请求响应之前或响应之后,做一些事情。
这里的Interceptor就和Filter、Struts的Interceptor很类似,提供它的主要作用就是为了很好的降低代码的耦合性,提供代码的内聚性。
下面我们就看看CXF的Interceptor是怎么样工作的。
1、我们就用上面的HelloWorldService,客户端的调用代码重新写一份,代码如下:
packagecom.hoo.client;
importorg.apache.cxf.interceptor.LoggingInInterceptor;
importorg.apache.cxf.interceptor.LoggingOutInterceptor;
importorg.apache.cxf.jaxws.JaxWsProxyFactoryBean;
importorg.apache.cxf.phase.Phase;
importcom.hoo.interceptor.MessageInterceptor;
importcom.hoo.service.IHelloWorldService;
/**
*function:
CXFWebService客户端调用代码
*@authorhoojo
*@createDate2011-3-16上午09:
03:
49
*@fileHelloWorldServiceClient.java
*@packagecom.hoo.client
*@projectCXFWebService
*@blog
*@emailhoojo_@
*@version1.0
*/
publicclassServiceMessageInterceperClient{
publicstaticvoidmain(String[]args){
//调用WebService
JaxWsProxyFactoryBeanfactory=newJaxWsProxyFactoryBean();
factory.setServiceClass(IHelloWorldService.class);
factory.setAddress("http:
//localhost:
9000/helloWorld");
factory.getInInterceptors().add(newLoggingInInterceptor());
factory.getOutInterceptors().add(newLoggingOutInterceptor());
IHelloWorldServiceservice=(IHelloWorldService)factory.create();
System.out.println("[result]"+service.sayHello("hoojo"));
}
}
上面的CXF的拦截器是添加在客户端,同样在服务器端也是可以添加拦截器Interceptor的。
运行后结果如下:
2011-3-187:
34:
00org.apache.cxf.service.factory.ReflectionServiceFactoryBeanbuildServiceFromClass
信息:
CreatingService{fromclasscom.hoo.service.IHelloWorldService
2011-3-187:
34:
00org.apache.cxf.interceptor.AbstractLoggingInterceptorlog
信息:
OutboundMessage
---------------------------
ID:
1
Address:
http:
//localhost:
9000/helloWorld
Encoding:
UTF-8
Content-Type:
text/xml
Headers:
{SOAPAction=[""],Accept=[*/*]}
Payload:
Envelopexmlns:
soap="http:
//schemas.xmlsoap.org/soap/envelope/">Body>sayHelloxmlns:
ns1="
--------------------------------------
2011-3-187:
34:
01org.apache.cxf.interceptor.AbstractLoggingInterceptorlog
信息:
InboundMessage
----------------------------
ID:
1
Response-Code:
200
Encoding:
UTF-8
Content-Type:
text/xml;charset=UTF-8
Headers:
{content-type=[text/xml;charset=UTF-8],Content-Length=[230],Server=[Jetty(7.2.2.v20101205)]}
Payload:
Envelopexmlns:
soap="http:
//schemas.xmlsoap.org/soap/envelope/">Body>sayHelloResponsexmlns:
ns1="say:
HelloWorld
sayHelloResponse>
Body>
Envelope>
--------------------------------------
[result]hoojosay:
HelloWorld
上面的部分信息是LoggingInterceptor输出的日志信息,分别在请求和响应的时候输出日志信息,还有输出请求的时候参数的信息以及响应的时候返回值的信息。
2、刚才是客户端添加Interceptor,现在我们自己编写一个Interceptor,这个Interceptor需要继承AbstractPhaseInterceptor,实现handleMessage和一个带参数的构造函数。
然后在服务器端添加这个Interceptor。
Interceptor代码如下:
packagecom.hoo.interceptor;
importorg.apache.cxf.interceptor.Fault;
importorg.apache.cxf.message.Message;
importorg.apache.cxf.phase.AbstractPhaseInterceptor;
/**
*function:
自定义消息拦截器
*@authorhoojo
*@createDateMar17,20118:
10:
49PM
*@fileMessageInterceptor.java
*@packagecom.hoo.interceptor
*@projectCXFWebService
*@blog
*@emailhoojo_@
*@version1.0
*/
publicclassMessageInterceptorextendsAbstractPhaseInterceptor{
//至少要一个带参的构造函数
publicMessageInterceptor(Stringphase){
super(phase);
}
publicvoidhandleMessage(Messagemessage)throwsFault{
System.out.println("############handleMessage##########");
System.out.println(message);
if(message.getDestination()!
=null){
System.out.println(message.getId()+"#"+message.getDestination().getMessageObserver());
}
if(message.getExchange()!
=null){
System.out.println(message.getExchange().getInMessage()+"#"+message.getExchange().getInFaultMessage());
System.out.println(message.getExchange().getOutMessage()+"#"+message.getExchange().getOutFaultMessage());
}
}
}
下面看看发布服务和添加自定义拦截器的代码:
packagecom.hoo.service.deploy;
importorg.apache.cxf.jaxws.JaxWsServerF