WebService:CXF开发
l
导入
CXF
中的 所有
jar
文件。可以通过
CXF_HOMElibWATCH_JARS
来观察各
jar
文件的用途和依赖关系。
CXF发布服务的两个类
l
ServerFactoryBean
?? --
FacotryBean
l
JaxWsServerFactoryBean
(
建议使用此类
)
/** ?* 使用ServerFactoryBean发布服务 ?* 使用CXF发布一个服务,与JDK6发布一个服务完全不同 ?* 即使是不使用@WebService注解,一样可以发布成功 ?* 即使此类没有对外公布的方法一样可以发布成功 ?*/ publicclass CxfOneServer { ? public String sayHi(){ ? return "Hello:"+new Date(); ? } ? public static void main(String[] args) { ? ServerFactoryBean bean =//声明实例 ? new ServerFactoryBean(); ? //绑定到发布地址的端口 ? bean.setAddress("http://127.0.0.1:9999/one"); ? //设置服务接口,如果没有接口,则为本类 ? bean.setServiceClass(CxfOneServer.class); ? //设置接口实现类,即服务类 ? bean.setServiceBean(new CxfOneServer()); ? bean.create();//发布服务 ? System.err.println("启动成功"); ? } } 客户端
l
使用
ServerFactoryBean
发布服务以后,在没有接口的情况下,可以使用
wsimport
生成的客户端代码调用成功。
l
但如果要使用
ClientProxyFactoryBean
客户端去调用服务器,则必须要先在服务器端创建一个接口。
(
一直以来,
Spring
都要求面向接口编程,而
cxf
与
Spring
能很好的整合,也就在此。
)
,所以,必须要重写服务器端的代码。这将使用
wsimport
生成的调用代码失效。
l
同时,
ClientProxyFactoryBean
由于要用到
CXF
环境,所以要导入
CXF
的所有包。
l
同时,如果是在本项目中调用,则可以直接使用本项目的接口。
如果在其他项目中调用,仍然需
wsimport
生成的类,但只需要一个接口。
publicclass Client { ? public static void main(String[] args) { ? ClientProxyFactoryBean bean =//创建客户端类 ? new ClientProxyFactoryBean(); ? //设置访问地址 ? bean.setAddress("http://localhost:9999/one"); ? //设置服务接口,直接使用本项目中的接口 ? bean.setServiceClass(CxfOne.class); ? //通过create方法返回接口实例 ? CxfOne s =??(CxfOne) bean.create(); ? String str = s.sayHi();//调用 ? System.err.println(str); ? } }
lJaxWsServerFactoryBean
是
ServerFactoryBean
的子类,也是功能扩展类。
l
但在
CXF
的
API
文档中没有提供此类
API,
请通过查看源代码的方式获取此类的帮助。
l
此类,必须要在被发布为服务的类上添加
@
WebService
注解,如果不加注解,虽然不
出错,但也不会对外暴露任何方法。 ????? 使用此类生成的wsdl文件更加规范。
l
以下是从它的源代码中找到的对此类的说明。
@WebService publicclass OneService { ? public String sayHi(){ ? return "Good"; ? } ? public static void main(String[] args) throwsException { ? JaxWsServerFactoryBeanbean? //使用jaxWs对其进行发布 ? ? = new JaxWsServerFactoryBean(); ? bean.setServiceBean(new OneService()); ? bean.setServiceClass(OneService.class); ? bean.setAddress("http://localhost:4444/one"); ? bean.create(); ? System.err.println("服务启动成功。。"); ? //Thread.sleep(1000*60*60); ? //System.exit(0); ? } }
在服务启动成功后,访问的方式为:http://localhost:4444/one?wsdl 创建成功以后,使用Wsimport或者wsdl2java生成的客户端代码,同样可以调用成功。 使用JaxWsProxyFactoryBean客户端调用
l
此调用过程与
ClientProxyFactoryBean
的要求一样,也必须要拥有一个接口。
l 此时,仍然可以使用 wsimport 生成接口,在其他项目的调用。 publicclass A{ publicstaticvoidmain(String[] args) { //Cxf2Servert = //newCxf2ServerService().getCxf2ServerPort(); //Strings = t.sayHello(); //System.err.println(s); JaxWsProxyFactoryBean bean = newJaxWsProxyFactoryBean(); bean.setAddress("http://localhost:9999/two"); //此外注册的必须是一个接口,否则将抛出异常信息 bean.setServiceClass(Cxf2Server.class); Cxf2Servers = (Cxf2Server) bean.create(); System.err.println(s.sayHello()); } }
如果不是使用spring的配置文件发布,可以没有接口文件,但在任何情况下建议拥有接口文件。如果使用spring的配置文件发布,则必须要拥有接口类。 wsdl2java生成客户代码:
l
在
cxf
中,也提供了一个用于生成客户端调用代码的工具。它的功能就如同
wsimport
一样,
可以生成一堆客户端调用的代码。
l
此工具位于
cxf_home
/bin
目录下。参数与
wsimport
有所不同。
l
它包含以下参数:
?
-
d
参数,指定代码生成的目录。
?
-
p
参数,指定生成的新的包结构。
l
需要说明的是,由于
wsdl2java
是根据
jdk1.7
生成的本地代码,所以,需要对生成的代码做一点点修改。
l
在命令行执行:
wsdl2java –d
.
http://
127.0.0.1:6666/helloworld?wsdl
1、注意:由于使用的是apache-cxf-2.4.0版本,它是支持jdk1.7的。所以,对于生成的Service要进行稍微的修改。 ?? 在jdk1.6中的javax.xml.ws.Service的构造方法接收二个参数为:(String url,QNameqname); ?? 在jdk1.7中的javax.xml.ws.Service的构造方法中接收三个参数为:(String url,QNameqname,features); 2、将生成的代码,拷贝到项目目录,然后使用以前相同方法调用。 ??? 注意:如果你对@WebMethod设置了header=true参数,将会在调用时多传递一个参数。它参数可以直接传null值。 ???????????? 对于这种情况,可以将header=true修改成header=false然后再重要获取客户端源代码。 3、使用cxf生成的客户端代码与wsimport差不多,甚至是一样,那为什么还要使用cxf呢? 它较好的发布方式、较容易的与其他服务器集成、及与Spring的完美结合都不得不让我们使用cxf。
/** ?* 使用java6来调用cxf生成的客户端类的服务 ?* 不管是用wsimport还是用wsdl2java生成的类基本上是完全一样的 ?*/ publicclass CxfServerJava6Client { ? public static void main(String[] args) { ? //调用使用wsimport生成的代码 ? IHelloWorldPortType hello =new IHelloWorld().getIHelloWorldPort(); ? String str = hello.sayHello("小王"); ? System.err.println(str); ? ? //调用使用wsdl2java生成的代码(一样) ? com.itcast.cxfserver2.javaclient.IHelloWorldPortTypeclient = ? newcom.itcast.cxfserver2.javaclient.IHelloWorld().getIHelloWorldPort(); ? String str2 = client.sayHello("CXF"); ? System.err.println(str2); ? } } 要想研究更多程序请见:cxf2.4_ws服务项目和cxf2.4_java6client客户端项目。 给服务器添加拦截器,类似于使用TCP/IPMonitor来捕获SOAP消息的过程。 server.getInInterceptors().add(newLoggingInInterceptor()); server.getOutInterceptors().add(newLoggingOutInterceptor());
l
LoggingInInterceptor
–
信息输入时的拦截器
–
请求
l
LoggingOutInterceptor
–
信息输出时的拦截器
-
响应
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |