CXF(webservice服務)私人學習筆記

俗話說“好記性不如爛筆頭”,編程的海洋如此的浩大,養成做筆記的習慣是成功的一步!


此筆記主要是CXF2.4.2版本的筆記,並且筆記都是博主自己一字一字編寫和記錄,有錯誤的地方歡迎大家指正。




1、說明:
<1.1>CXF的功能是提供了用於方便地構建和開發 Web 服務的可靠基礎架構,使Web Service開發的簡單框架。
<1.2>所需要導入的jar包:CXF的核心jar包是cxf-2.4.2.jar,但所依賴的jar包非常多,需要把lib下的所有58個jar包全部導入。
<1.3>當CXF與Spring框架整合時,還需要額外的導入Spring的jar包。
<1.4>如果不是綁定tomcat服務器來運行,只是使用普通的方法運行時,CXF會調用自帶的jetty服務器進行啓用來提供服務,
反之,會直接使用tomcat來提供web Service服務。
<1.5>使用CXF也還需要用到註解@WebService,表示此類事SebService服務類,@WebMethod(exclude=true)表示某個方法不給遠程共享。但本地可以調用。
<1.6>所謂本地,指在統一進程中運行,如同一個項目中調用。
而遠程,是指在不同進程間,如Tomcat6.0訪問Tomcat7.0的資源,因爲Tom6與Tom7不是兩個Tom各自運行,故是屬於遠程調用。
<1.7>對外提供的方法必須是public的,且不能使static 和 final類型的。

<1.8>使用WebService時,如果是不同的語言間相互調用,參數可以是java的集合(List/Set/Map),但是返回參數不能是java的集合(List/Set/Map),否則客戶端無法使用,可以手動轉換成json格式的字符串。


<1.9>使用jdk6.0的wsimport的命令解析WebSerice的WSDL後,如果參數是個對象,那麼對象的屬性不能直接使用基本類型,而是使用JAXBElement對象進行包裝:
JAXBElement<String> str=new JAXBElement<String>(new QName("http://model.ihkmsyf.hfhh.cn","houseName"),String.class,"abc");
http://model.ihkmsyf.hfhh.cn是通過解析後的WSDL的封裝對象裏查看到的命名空間,houseName是名稱,這兩個參數必須一致才能進行傳遞到服務端。

2、在普通的java Project中發佈web Service的方式(必須要在WebService服務類上加註解@WebService):
//創建jaxws對象。jaxws:Jaca And Xml Web Service
JaxWsServerFactoryBean factory=new JaxWsServerFactoryBean();
//設置地址。訪問時必須是http://localhost:8888/say?wsdl,否則會報錯
String address="http://localhost:8888/say";
factory.setAddress(address);
//設置服務類
factory.setServiceBean(new CxfWS());
//設置訪問日誌,默認是輸出到控制檯。
factory.getInInterceptors().add(new LoggingInInterceptor());
//設置返回給客戶端的信息記錄日誌,默認是輸出到控制檯。
factory.getOutInterceptors().add(new LoggingOutInterceptor());
//啓動CXF內置的jetty服務器。此時將不再使用JDK自帶的mini服務器
factory.create();

<2.1> 注意,訪問時因爲http://localhost:8888/say並沒有任何數據,因此CXF會報錯,只能直接訪問WSDL文檔:http://localhost:8888/say?wsdl

3、CXF與Spring框架的整合。
<3.1>配置spring.xml:
增加頭文件內容:
xmlns:jaxws="http://cxf.apache.org/jaxws"

"http://cxf.apache.org/jaxws 
http://cxf.apache.org/schemas/jaxws.xsd"

完整的spring.xml配置文件:
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://cxf.apache.org/jaxws 
http://cxf.apache.org/schemas/jaxws.xsd">

<!-- 將webservice服務類,註冊到springIOC容器中 -->
<bean id="CxfWSID" class="cn.itcast.cxf.CxfWS"/>

<!-- 
將webservice服務類,暴露給遠程客戶端,以便調用
與傳統的main()方法類似
目的是:發佈webservice服務到指定的URL上

address:表示發佈的URL地址,但這裏不需要http://,只要服務名即可
bean:表示真正提供服務的類
-->
<jaxws:server address="/cat">
<jaxws:serviceBean>
<ref bean="CxfWSID"/>
</jaxws:serviceBean>
</jaxws:server>
 
<3.2>如果是使用Servlet,因爲Servlet並不是有Spring來維護,則無法通過IOC進行注入服務類,則
需要在Servlet中獲取ApplicationContext,直接通過getBeans()來獲取WebService的服務類。
獲取方法:
ApplicationContext ac=WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());


<3.3>如果是使用Struts2,則可以直接使用IOC來注入WebService的服務類。

<3.4>配置web.xml文件
<!-- 配置org.apache.cxf.transport.servlet.CXFServlet類
作用在於:將服務類,轉成WSDL描述文件
注意路徑:/myservice/*,值必須訪問項目名/myservice,纔會得到一個鏈接WSDL的頁面
-->  
  <servlet>
<servlet-name>CXF</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
 </servlet>
 
 <servlet-mapping>
<servlet-name>CXF</servlet-name>
<url-pattern>/myservice</url-pattern>
 </servlet-mapping>

<3.5注意事項>
(1)CXFServlet的<url-pattern>/myservice/*</url-pattern>,是指必須要訪問到http:localhost:8080/項目名/myservice,
纔會顯示一個鏈接WSDL的頁面。

(2)address="/cat",表示當通過http:localhost:8080/項目名/myservice顯示的鏈接WSDL的頁面地址是
http:localhost:8080/cat?WSDL。

(3)如果Web項目也整合了Struts2框架,則必須修改Struts2攔截器的攔截地址,因爲struts2的攔截地址是/*,默認攔截所有請求,導致
原本訪問CXFServlet的/myservice也被攔截了,攔截器會找這個路徑下的Action,導致最後找不到Action而引起報錯。
解決方式有兩種:
方式1(不建議使用).修改Struts2的攔截地址:
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/struts2/*</url-pattern>
 </filter-mapping>

方式2.自定義一個過濾器Filter,且必須在struts2前聲明,判斷請求地址如果是/myservice,則轉發到CXFServlet。





4、cxf與Spring的客戶端整合方式(在Spring的配置文件xml中增加配置):
<!-- 配置ws的客戶端 -->
<jaxws:client id="cardImgreconClient"
<!--提供服務的服務端地址-->
address="http://10.71.9.10:8080/cxfServerX/ImgReconCard"
<!--提供服務類的接口,必須與服務端的接口一致-->
serviceClass="com.wintone.webservice.CardImgrecon"/>




5、在使用cxf與Spring的客戶端整合方式時,要求接口類的包路徑必須一樣,否則會拋出異常:
org.apache.cxf.interceptor.Fault: Unexpected wrapper element {****}

 同時,最好保持類名的一致性,還有方法的一致性,以便出現其他錯誤。
 
 
 
 
6、凡是提供webservice服務的接口與實現類,都必須在類名或接口名上增加@WebService 的註解,表示是提供ws服務的。
注意,無論是客戶端的接口類還是服務端的接口類,都必須添加該註解。



7、cxf的服務端與spring整合時,如果想讓cxf的部分模塊對象也交給spring管理,可以引入相應的cxf的xml配置文件:
(1)讓spring管理 cxf的核心組件、 SOAP binding、servlet transport,則配置:
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

(2)讓spring管理 cxf的所有模塊對象,則配置(不建議用此方式,因爲如果沒有使用cxf的全部功能,卻生成全部模塊的對象,浪費資源):
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath*:META-INF/cxf/cxf-extension-*.xml" />

或者配置爲:

<import resource="classpath:META-INF/cxf/cxf.xml" />


說明:META-INF/cxf/cxf.xml等這些配置文件在cxf.jar包中,只需要導入cxf.jar到項目中,不需要再拷貝對應的文件到自己的項目META-INF下。
 上面的import並不是必須的,如果不引入相應的配置文件,則cxf自己管理模塊對象,依舊可以使用cxf提供的ws服務。
 如果項目中有使用spring,建議cxf的核心模塊組件對象交由spring統一管理。
 


發佈了48 篇原創文章 · 獲贊 10 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章