簡單的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");