简单的CXF应用
1.1 服务端开发
1)首先下载CXF开发要用到的相关包,目前最新版本是apache-cxf-2.3.1。下载地址:
http://www.apache.org/dyn/closer.cgi?path=%2Fcxf%2F2.3.1%2Fapache-cxf-2.3.1.zip
下载解压后在apache-cxf-2.3.1目录下lib目录下,有所有要用到的jar包。
2)建一个web项目,将apache-cxf-2.1.3\lib目录下所有包添加到项目中。
注:这些包里面有jetty,cxf,spring的相关包,可以根据需要进行添加,如果不和spring进行整合,则不需要spring相关包。Jetty是一个类似于tomcat的web服务器,内置在cxf中,用于发布web服务。如果用jetty发布服务,则需要添加它的包,如果用tomcat则不需要。
3)写好一个接口和实现类(具体见demo中IHelloService和HelloServiceImpl),本demo中数据绑定方式采用cxf默认的jaxb方式,也可以采用aegis,其优点是不用jaxb中的注解方式。(基于SOAP的Web服务可用单个Java类的实现,但是最好是用“接口+实现”的方式来实现最佳。Web服务的接口称为SEI,即ServiceEndpoint Interface;而Web服务的实现称为SIB,即Service Implementation Bean。 SIB可以是一个POJO,也可以是无状态的会话EJB。)
4)发布服务
一种是通过CXF内置的Jetty应用服务器发布(见方法一,二),一种是通过tomcat发布(见方法三)。
Ø 方法一:使用SunJAX-WS 2中Endpoint.publish进行发布。(不需要其他配置与包)
Endpoint endpoint =
Endpoint.publish("http://localhost:8080/WSCXF/helloService",
new HelloServiceImpl());//这里是实现类
System.out.println("WS发布成功!");
Ø 方法二:用CXF的JaxWsServerFactoryBean类进行发布。(需要CXF相关包)
HelloServiceImpl impl = new HelloServiceImpl();
JaxWsServerFactoryBean factoryBean = newJaxWsServerFactoryBean();
factoryBean.setAddress("http://localhost:8080/WSCXF/helloService");
factoryBean.setServiceClass(IHelloService.class);//接口类
factoryBean.setServiceBean(impl);
factoryBean.create();
System.out.println("WS发布成功!");
方法一或者方法二都是发布到Jetty下。在main方法中运行方法一或者方法二代码,web服务就发布成功了。
Ø 方法三:利用cxf和spring整合在tomcat下进行发布。具体方法在后面的spring整合cxf时讲到。
Ø 方法四:重写loadBus方法。
书写一个类覆盖org.apache.cxf.transport.servlet.CXFNonSpringServlet的loadBus方法指定BUS以及发布你的web服务。
具体可查阅资料:
http://blog.csdn.net/zq9017197/archive/2010/12/26/6099684.aspx
查看web服务是否发布成功:
访问http://localhost:8080/WSCXF/helloService?wsdl 查看wsdl文件
1.2 客户端调用
客户端调用只需要服务端提供一个webservice的发布地址即可。不关心服务端发布方式等。
1)客户端代码生成
Ø 方法一:使用MyEclipse工具生成。
new-other-myeclipse-web service-web service client根据设置向导可以生成客户端,但最好使用CXF的wsdl2java来完成,因为CXF2.2+版本开始支持JAX-WS2.1规范,而MyEclipse自带的是xfire的一个插件,生成的客户端代码可能不是最新规范的。
Ø 方法二:通过wsdl2java的命令生成客户端代码。
先进入dos窗口,进入apache-cxf-2.3.1\bin所在目录,输入命令:
wsdl2java -pcom.jaxb.client -d e:/ http://127.0.0.1:8080/WSCXF/helloService?wsdl
命令格式为:wsdl2java –p 包名 –d 生成代码存放目录wsdl的url
其中的wsdl的url为要调用的webservice的服务地址
附加:wsdl2java用法:
wsdl2java -p com-d src -all aa.wsdl
-p 指定其wsdl的命名空间,也就是要生成代码的包名;
-d 指定要产生代码所在目录;
-client 生成客户端测试web service的代码;
-server 生成服务器启动web service的代码;
-impl 生成web service的实现代码;
-ant 生成build.xml文件;
-all 生成所有开始端点代码:types,serviceproxy, service interface, server mainline, client mainline, implementation object,and an Ant build.xml file。
详细用法见:http://cwiki.apache.org/CXF20DOC/wsdl-to-java.html
2)新建一个web客户端项目,将生成的客户端代码拷贝到src下。
3)调用web服务
Ø 方法一:使用标准的JAX-WS的API完成客户端调用(不需要导入任何CXF包)
//注意。此处http://service.jaxb.com/来源于wsdl文件中targetNamespace
QName qName =
newQName("http://service.jaxb.com/","HelloServiceImplService");
HelloServiceImplService helloServiceImplService =
new HelloServiceImplService(
new URL("http://localhost:8080/WSCXF/helloService?wsdl"),qName);
IHelloService helloService
=(IHelloService)helloServiceImplService.getPort(IHelloService.class);
Ø 方法二:使用CXF中JaxWsProxyFactoryBean客户端代理工厂调用web服务(需要导入CXF相关包)
JaxWsProxyFactoryBean soapFactoryBean = newJaxWsProxyFactoryBean();
soapFactoryBean.setAddress("http://localhost:8080/WSCXF/helloService");
soapFactoryBean.setServiceClass(IHelloService.class);
Object o = soapFactoryBean.create();
IHelloService helloService = (IHelloService)o;
Ø 方法三:
String endPointAddress = "http:// localhost:8080/WSCXF/helloService";
Service service = Service.create(
newQName("http://service.jaxb.com/","IHelloService"));
service.addPort(
new QName("http://service.jaxb.com/","IHelloServicePort");,
SOAPBinding.SOAP11HTTP_BINDING, endPointAddress);
IHelloService helloService =service.getPort(IHelloService.class);
Ø 方法四:(需要导入CXF相关包)
JaxWsDynamicClientFactory dcf =JaxWsDynamicClientFactory.newInstance();
org.apache.cxf.endpoint.Client client =
dcf.createClient("http://127.0.0.1:8080/WSCXF/helloService?wsdl");
//sayHello 为接口中定义的方法名称 张三为传递的参数 返回一个Object数组
Object[] objects=client.invoke("sayHello","张三");
//输出调用结果
System.out.println(objects[0].toString());
2.CXF和Spring整合
CXF可以很好的与Spring整合,然后发布在tomcat下,只需要简单的Spring配置即可。
2.1 服务端开发
1)新建web项目,并添加相关包。(包括spring和cxf相关包)
2)写好一个接口和实现类。(见demo)
3)新建beans.xml文件。
<?xml version="1.0"encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxwshttp://cxf.apache.org/schemas/jaxws.xsd">
<!--spring发布web服务配置 -->
<importresource="classpath:META-INF/cxf/cxf.xml" />
<importresource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<importresource="classpath:META-INF/cxf/cxf-servlet.xml" />
<bean id="helloService"class="com.jaxb.service.HelloServiceImpl" />
<!--
<bean id="helloService"class="com.aegis.service.HelloServiceImpl" />
-->
<!--endpoint 方式发布web服务和 server方式一样 -->
<!--
<jaxws:endpointid="helloServiceWs" address="/helloService"
implementor="#helloService"/>
-->
<!--
另一种写法,建议不要用这种方法 ,如果实现类有的属性要通过spring依赖注入的话,
这种方法只是简单的new个实现类,他的属性没有通过spring依赖注入给注入值
-->
<!--
<jaxws:endpointid="helloServiceWs" address="/helloService"
implementor="com.jaxb.service.HelloServiceImpl"/>
-->
<!—下面这个是wss4j的配置,后面会讲到相关知识,需要配置在spring配置文件中 -->
<!--wss4j 服务端配置 -->
<bean id="wss4jInInterceptor"
class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
<entrykey="action" value="UsernameToken" />
<!--<entry key="passwordType" value="PasswordText" />-->
<!--密码使用MD5密文发送 -->
<entrykey="passwordDigest" value="PasswordText" />
<entrykey="passwordCallbackClass"
value="com.security.service.ServerPasswordCallbackHandler"/>
</map>
</constructor-arg>
</bean>
<jaxws:serverid="helloServiceWs" address="/helloService">
<jaxws:serviceBean>
<refbean="helloService" />
</jaxws:serviceBean><!--使用这种方法发布web服务 -->
<jaxws:inInterceptors>
<refbean="wss4jInInterceptor" />
</jaxws:inInterceptors><!—wss4j配置 -->
<!--<jaxws:serviceFactory>
<refbean="jaxWsServiceFactoryBean" />
</jaxws:serviceFactory> --><!—数据绑定方式配置 -->
</jaxws:server>
<!-- 通过Spring创建数据绑定的类-->
<!--<bean id="aegisBean"class="org.apache.cxf.aegis.databinding.AegisDatabinding" />
<bean id="jaxWsServiceFactoryBean"
class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean">
<property name="wrapped" value="true" />
<property name="dataBinding" ref="aegisBean"/>
</bean> -->
</beans>
4)配置web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/beans.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!—在tomcat中发布需要配置servlet -->
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/ws/*</url-pattern>
</servlet-mapping>
5)发布web项目
因为在web.xml里面配置了servlet,则可以将项目发布到tomcat下,启动tomcat即可。
6)访问wsdl
http://localhost:8080/WSCXF/ws/helloService?wsdl
2.2 客户端调用
1)新建一个web客户端项目,用wsdl2java生成客户端代码。将生成的客户端代码拷贝到src下。添加spring相关包。
2)配置spring配置文件。
beans.xml存放在src目录下,具体配置如下:
<?xml version="1.0"encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxwshttp://cxf.apache.org/schemas/jaxws.xsd">
<!-- wss4j 配置在客户端,后面有讲到相关知识 -->
<!--wss4j 客户端配置 -->
<beanid="wss4jOutInterceptor"
class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
<entrykey="action" value="UsernameToken" />
<entrykey="user" value="Fetion" />
<!--<entry key="passwordType" value="PasswordText" />-->
<!--密码使用MD5密文发送 -->
<entrykey="passwordDigest" value="PasswordText" />
<entrykey="passwordCallbackClass"
value="com.security.client.ClientPasswordCallbackHandler"/>
</map>
</constructor-arg>
</bean>
<jaxws:client id="helloServeiceClient"
address="http://localhost:8080/WSCXF/ws/helloService"serviceClass="com.jaxb.client.IHelloService">
<jaxws:outInterceptors>
<refbean="wss4jOutInterceptor" />
</jaxws:outInterceptors><!--wss4j客户端配置-->
</jaxws:client>
</beans>
2)调用web服务
在main方法中运行:
ClassPathXmlApplicationContext app = newClassPathXmlApplicationContext("beans.xml");//此处beans.xml放在src下,也需要放在其他目录下,但需要注明清楚
//获取webservice服务的操作接口
IHelloServicehelloService = (IHelloService)app.getBean("helloServeiceClient");