京山游俠

          專注技術,拒絕扯淡
          posts - 50, comments - 868, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理
          在前面的隨筆中,我講了我的網站架構,這樣的架構決定了我的網站中必須得用到WebService。比如,在用戶注冊的時候,用戶數據主要是保存在內容服務器中,但是同時也要將部分數據提交到索引服務器中,這時,就可以讓內容服務器訪問索引服務器提供的WebService來提交數據;還可以讓內容服務器通過定時任務,訪問索引服務器的WebService來提交統計數據。

          我的網站使用SpringSide 2.0開發,在SpringSide 2.0中,默認使用的是XFire來提供WebService,但是我按照文檔進行操作,結果卻失敗了。于是我向江南白衣請教,白衣推薦我使用CXF的最新版本,于是我到官方網站下載了CXF的最新版,按照示例來了一遍,很快就成功了。由此可見,使用CXF不僅簡單,而且成功率高。因此,我在這里把我的經驗和大家分享。

          第一步,下載CXF的最新版本,下載地址如下圖:
          01.PNG


          第二步,將CXF中的lib文件夾中的下列jar文件拷貝到我們項目的webapp/WEB-INF/lib目錄下:
          commons-logging-1.1.jar
          geronimo-activation_1.1_spec-
          1.0-M1.jar?(or?Sun's?Activation?jar)
          geronimo-annotation_1.0_spec-
          1.1.jar?(JSR?250)
          geronimo-javamail_1.4_spec-
          1.0-M1.jar?(or?Sun's?JavaMail?jar)
          geronimo-servlet_2.5_spec-
          1.1-M1.jar?(or?Sun's?Servlet?jar)
          geronimo-ws-metadata_2.0_spec-
          1.1.1.jar?(JSR?181)
          jaxb-api-
          2.0.jar
          jaxb-impl-
          2.0.5.jar
          jaxws-api-
          2.0.jar
          neethi-
          2.0.jar
          saaj-api-
          1.3.jar
          saaj-impl-
          1.3.jar
          stax-api-
          1.0.1.jar
          wsdl4j-
          1.6.1.jar
          wstx-asl-
          3.2.1.jar
          XmlSchema-
          1.2.jar
          xml-resolver-
          1.2.jar

          cxf-
          2.0-incubator.jar


          這里有一些包我的項目中本身已經帶有了,只不過CXF中提供的版本要更新一些。把這些包拷貝到項目中后,可以刪除項目中的較低的版本,同時刪除所有和XFire有關的包。當然,不刪除也可以,因為我試過了,就算項目中存在多個不同版本的包,也不會發生沖突。

          當然,光拷貝這些包到項目中,還不能保證開發的順利進行,還需要在Eclipse中設置項目的庫,如下圖:
          03.png

          在這里,我不得不說一下另外一個問題,那就是啟動Tomcat服務器的時候,經常發生java.lang.OutOfMemoryError: PermGen space異常,出現這個異常是什么原因呢?在網上搜到的答案是這樣的:PermGen space的全稱是Permanent Generation space,是指內存的永久保存區域,這塊內存主要是被JVM存放Class和Meta信息的,Class在被Loader時就會被放到PermGen space中,它和存放類實例(Instance)的Heap區域不同,GC(Garbage Collection)不會在主程序運行期對PermGen space進行清理,所以如果你的應用中有很多CLASS的話,就很可能出現PermGen space錯誤,這種錯誤常見在web服務器對JSP進行pre compile的時候。如果你的WEB APP下都用了大量的第三方jar, 其大小超過了jvm默認的大小(4M)那么就會產生此錯誤信息了。

          本來,使用SpringSide 2.0就已經包含了許多的第三方包,容易出現這個問題,現在加入CXF依賴的這些包,就不可避免要出現這個問題了。這個問題的解決方法有兩個,其一是不使用SUN的JDK。當然,我也懶得去下載一個別的JDK,因此就選擇了第二個方法,那就是修改Tomcat的啟動文件。

          找到SpringSide2.0\misc\servers\tomcat-5.5.17\bin文件夾下的catalina.bat文件,使用記事本打開,找到如下行:
          set JAVA_OPTS=

          將這一行進行修改,加入啟動參數,如下:
          set JAVA_OPTS=%JAVA_OPTS% -Xms512m -Xmx1024m -XX:MaxNewSize=512m -XX:MaxPermSize=512m -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.logging.config.file="%CATALINA_BASE%\conf\logging.properties":noJuli

          解決了以上這些問題,就可以正式使用CXF了。


          第三步,修改webapp/WEB-INF/web.xml文件,將以前的

          <servlet>
          ??
          <servlet-name>xfire</servlet-name>
          ??
          <servlet-class>org.codehaus.xfire.spring.XFireSpringServlet</servlet-class>
          </servlet>
          <servlet-mapping>
          ??
          <servlet-name>xfire</servlet-name>
          ??
          <url-pattern>/service/*</url-pattern>
          </servlet-mapping>

          修改為:
          <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>/service/*</url-pattern>
          </servlet-mapping>

          即可。


          第四步,定義一個提供WebService的接口。在我的項目中,我準備只提供一個WebService,即IndexService,這個服務中提供多個方法來分別滿足索引服務器的各種功能。目前,我還只開發到了用戶注冊模塊,需要向索引服務器提交用戶數據,因此,暫時提供一個addUser方法作為示例,如下:
          package?com.yumdays.service;

          import?javax.jws.WebService;
          import?com.yumdays.model.SUser;

          @WebService
          public?interface?IndexService?{
          ????
          public?boolean?addUser(SUser?user,String?adminName,String?adminPassword);
          }

          而它的實現類如下:
          package?com.yumdays.service;

          import?com.yumdays.model.SUser;
          import?javax.jws.WebService;

          @WebService(endpointInterface?
          =?"com.yumdays.service.IndexService")
          public?class?IndexServiceImpl?implements?IndexService?{

          ????
          public?boolean?addUser(SUser?user,?String?adminName,?String?adminPassword)?{
          ????????
          //?TODO?自動生成方法存根
          ????????return?false;
          ????}

          }


          ?第五步,在項目的src/resource/spring目錄下,刪除所有和XFire有關的配置文件,添加一個cxf-beans.xml文件,其內容如下:

          <?xml?version="1.0"?encoding="UTF-8"?>
          <beans?xmlns="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/beans?http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
          ????http://cxf.apache.org/jaxws?http://cxf.apache.org/schemas/jaxws.xsd"
          >

          ????
          <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"?/>

          ????
          <bean?id="indexServiceBean"?class="com.yumdays.service.IndexServiceImpl"?/>
          ????
          <jaxws:endpoint?id="indexService"?implementor="#indexServiceBean"?address="/IndexService"?/>
          ??????
          </beans>

          現在,重新構建項目,部署,啟動Tomcat,就可以通過訪問http://www.yumdays.com/service/IndexService?wsdl來測試該WebService是否成功被部署了。如下圖:
          02.PNG


          第六步,創建客戶端,這一步非常的容易,只需要下面這樣的配置:
          <?xml?version="1.0"?encoding="UTF-8"?>
          <beans?xmlns="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/beans?http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
          ????http://cxf.apache.org/jaxws?http://cxf.apache.org/schemas/jaxws.xsd"
          >

          ????
          <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"?/>

          ????
          <bean?id="client"?class="com.yumdays.service.IndexService"?factory-bean="clientFactory"?factory-method="create"/>
          ????
          ????
          <bean?id="clientFactory"?class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
          ??????
          <property?name="serviceClass"?value="com.yumdays.service.IndexService"/>
          ??????
          <property?name="address"?value="http://www.yumdays.com/service/IndexService"/>
          ????
          </bean>
          ????
          </beans>

          就可以獲得一個名稱為client的bean,通過該bean,就可以非常方便的訪問索引服務器提供的功能。

          評論

          # re: 在SpringSide 2.0中使用CXF提供Web Service服務  回復  更多評論   

          2008-03-09 11:57 by TonySoft
          其實使用XFire比使用CXF要簡單一些,但是CXF提供了更多的高級特性,如果項目允許,切換到CXF是一個不錯的選擇。

          # re: 在SpringSide 2.0中使用CXF提供Web Service服務  回復  更多評論   

          2008-03-18 10:23 by web
          我和樓主的配置一樣為什么通不過。
          org.apache.cxf.binding.soap.SoapFault: Error reading XMLStreamReader.
          org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:70)
          org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:35)
          org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:208)
          org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:96)
          org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor.handleMessage(ReadHeadersInterceptor.java:183)
          org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor.handleMessage(ReadHeadersInterceptor.java:56)
          org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:208)
          org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:429)
          org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1955)
          org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1791)
          org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:66)
          org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:575)
          org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
          org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:208)
          org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:276)
          org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:222)
          org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:73)
          org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:135)
          $Proxy15.getCounter(Unknown Source)
          com.hbby.installation.web.action.LoginAction.login(LoginAction.java:83)
          sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
          sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
          java.lang.reflect.Method.invoke(Method.java:585)
          org.apache.struts.actions.ActionDispatcher.dispatchMethod(ActionDispatcher.java:335)
          org.apache.struts.actions.ActionDispatcher.dispatchMethod(ActionDispatcher.java:318)
          org.apache.struts.actions.ActionDispatcher.execute(ActionDispatcher.java:220)
          com.hbby.installation.web.action.LoginAction.execute(LoginAction.java:44)
          org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431)
          org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236)
          org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
          org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
          javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
          javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
          com.hbby.system.EncodingFilter.doFilter(EncodingFilter.java:36)

          # re: 在SpringSide 2.0中使用CXF提供Web Service服務  回復  更多評論   

          2008-03-18 20:09 by youxia
          你還是把項目里面的庫文件整理一下,把名稱相同但版本較低的jar包刪除。你出的錯可能是因為XML解析錯誤引起的。

          # re: 在SpringSide 2.0中使用CXF提供Web Service服務[未登錄]  回復  更多評論   

          2008-05-05 09:34 by 阿樂
          上面的朋友是不是安裝了卡吧殺毒軟件,把它暫停一下試試.

          # re: 在SpringSide 2.0中使用CXF提供Web Service服務  回復  更多評論   

          2008-06-16 13:30 by hejianhuacn
          @youxia
          應該是卡巴的問題,我也碰到了,把它的Web防護關掉就好了

          # re: 在SpringSide 2.0中使用CXF提供Web Service服務  回復  更多評論   

          2008-09-02 14:53 by Eclipse_lijp
          按照樓主步驟,CXF最后部署失敗,訪問http://localhost:8080/cxfServer/service/WebServiceSample?wsdl

          頁面報錯:
          java.lang.NoSuchMethodError: org.w3c.dom.Document.setXmlStandalone(Z)V
          org.apache.cxf.transport.http.WSDLQueryHandler.updateDoc(WSDLQueryHandler.java:253)
          org.apache.cxf.transport.http.WSDLQueryHandler.writeResponse(WSDLQueryHandler.java:201)
          org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:152)
          org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke(AbstractCXFServlet.java:174)
          org.apache.cxf.transport.servlet.AbstractCXFServlet.doGet(AbstractCXFServlet.java:156)
          javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
          javax.servlet.http.HttpServlet.service(HttpServlet.java:802)

          望賜教,謝謝!

          # re: 在SpringSide 2.0中使用CXF提供Web Service服務  回復  更多評論   

          2008-09-04 14:55 by zhaoyutong
          樓主,你好,我已經百度了cxf 官網的User guide 所有文章,但是有一些地方還沒明白,我心情很沉重。我覺得我還是不會cxf

          但是當我看到了這段話。
          我的網站使用SpringSide 2.0開發,在SpringSide 2.0中,默認使用的是XFire來提供WebService,但是我按照文檔進行操作,結果卻失敗了。于是我向江南白衣請教,白衣推薦我使用CXF的最新版本,于是我到官方網站下載了CXF的最新版,按照示例來了一遍,很快就成功了。由此可見,使用CXF不僅簡單,而且成功率高。因此,我在這里把我的經驗和大家分享。

          以及文章的下邊的內容。我覺得我是個高手了。如果我有你對待事物的態度就好了

          這里www.frcircle.com有我收集的一些資料。 我覺得webservice是個龐大的體系

          # re: 在SpringSide 2.0中使用CXF提供Web Service服務  回復  更多評論   

          2010-09-30 15:09 by 刷刷刷
          樓上是sb
          主站蜘蛛池模板: 英吉沙县| 汉寿县| 柳林县| 汉中市| 山阳县| 庐江县| 瓮安县| 扎兰屯市| 方山县| 蓬溪县| 湖州市| 芷江| 舟曲县| 兴城市| 连云港市| 陆川县| 澄迈县| 长寿区| 长垣县| 临潭县| 汕头市| 沂水县| 闽侯县| 民和| 平安县| 濮阳县| 襄垣县| 玛多县| 绵阳市| 育儿| 眉山市| 涿州市| 邵阳县| 青海省| 安庆市| 茌平县| 宜君县| 翁牛特旗| 陇南市| 南投县| 张北县|