<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    我的漫漫程序之旅

    專注于JavaWeb開發
    隨筆 - 39, 文章 - 310, 評論 - 411, 引用 - 0
    數據加載中……

    XFire生火指南下半部

    XFire生火指南下半部,主要包括JSR181,Client API與測試部分。

    作者:江南白衣

    本文來自SpringSide WIki,請留意Wiki上的最新版本。(wiki于11.27更新)。

    請先閱讀:XFire生火指南(上)

    1. JSR181

         JSR181式通過annotated POJO ,零配置文件的導出Web服務,是BEA倡導的,JavaEE5里的正規方式, XFire作了良好的支持。

         但是,XFire關于JSR181方式的文檔還不夠清晰,請完整閱讀本節以避免其中的數個陷阱。

    1.1 參考文章

    • Spring, Hibernate and XFire
    • Webservices with Spring, XFire and jsr181
    • Basic Spring Web services with XFire and JSR 181
    • XFire JSR181參考文檔

    1.2 ApplicationContext.xml

        因為配置都寫在annotation,applicationContext.xml文件的內容比較固定。需要注意JSR181WebAnnotations與HandlerMapping不能lazy init.

    <beans default-autowire="byName"  default-lazy-init="true">
      
    <!--引入XFire的預配置文件-->
     
    <import resource="classpath:org/codehaus/xfire/spring/xfire.xml"/> 

     
    <!-- 獲得applicationContext中所有bean的JSR181 annotation -->
     
    <bean id="webAnnotations" class="org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations"  lazy-init="false"/>


     
    <!-- 定義handler mapping,將所有JSR181定義的bean導出為web service -->
     
    <bean id="jsr181HandlerMapping" class="org.codehaus.xfire.spring.remoting.Jsr181HandlerMapping"  lazy-init="false">
      
    <property name="xfire" ref="xfire"/>
      
    <property name="webAnnotations" ref="webAnnotations"/>
     
    </bean>
    </beans>

    1.3 Interface+Impl模式

       不同于XFire傳統模式,窄接口不是必須的,只是考慮到client如果也使用XFire時,有個接口好生成Client而已。

       如果采用Interface,Interface將擔任主要的配置工作。

       首先定義@WebService,可定義自己的NameSpace,如果不定義將采用NameSpace的默認生成算法。

       接口中的函數將默認全部導出,不需要再用@WebMethod注釋,可以如下例般進行更進一步配置:

    @WebService(targetNamespace = "http://www.springside.org.cn")
    public interface BookService {
      @WebResult(name 
    = "SearchResult")
      List
    <Book> findBooksByCategory(@WebParam(name = "category", header = true)String cateoryId);
    }

           Manager不是純粹的POJO,需要帶上@WebService注釋,指明InterFace。

    @WebService(serviceName = "BookService"
    endpointInterface 
    = "org.springside.bookstore.components.xfire.server.jsr181.BookService")
    public class BookManager implements BookService {...}

          陷阱一:XFire JSR181參考文檔 中在Interface中以@WebService(name="BookService")來定義ServiceName,這個做法看起來也比較合理,但實際上需要在Manager中以@WebService(serviceName ="BookService") 來定義,比較古怪。

    1.4 純POJO模式

        參考文檔中的例子,需要配置@WebMethod 指定需要導出的服務

    @WebService(name = "EchoService", targetNamespace = "http://www.openuri.org/2004/04/HelloWorld")
            
    public class Jsr181EchoService
    {
        @WebMethod(operationName 
    = "echoString", action = "urn:EchoString")
        @WebResult(name 
    = "echoResult")
        
    public String echo(@WebParam(name = "echoParam", header = true) String input)
        {
            
    return input;
        }
    }

    1.5 Client注意事項

        陷阱二:和傳統模式的client有一點最大的區別,第3個參數需要是實際的Manager類,而不是接口類:

    Service serviceModel = new AnnotationServiceFactory().create(BookManager.class);

    2. Client

    XFire的Client并不算強項,一共有三種模式:

    2.1 Client開發者擁有Web服務端的class

      Client與Server是同一個開發團隊也好,Server端團隊以jar形式提供開發包也好,反正如果能拿到服務端的接口Class和Entity類及aegis 配置文件的話。

      傳統模式:

    Service serviceModel = new ObjectServiceFactory().create(BookService.class);
    BookService service 
    = (BookService) new XFireProxyFactory().create(serviceModel, serviceURL);
    service.findBooksByCategory(cateoryId);

      JSR181模式,注意這里Server端開發組需要向Client提供BookService的實現類BookManager,而不止于接口類,有點危險: 

    Service serviceModel = new AnnotationServiceFactory().create(BookManager.class);
    BookService 
    = (BookService) new XFireProxyFactory().create(serviceModel, serviceURL);
    service.findBooksByCategory(cateoryId);

      SpringSide 用泛型封裝了一個XFireClientFactory,調用代碼如下:

    BookService service = XFireClientFactory.getClient(serviceURL, BookService.class);
    BookService service 
    = XFireClientFactory.getJSR181Client(serviceURL, BookService.class, BookManager.class);

    2.2 動態模式

        動態模式不需要服務端的class,不過性能和復雜對象映射等估計做得不會太好。

    Client client = new Client(new URL("http://www.webservicex.net/CurrencyConvertor.asmx?WSDL"));

    Object[] results 
    = client.invoke("ConversionRate"new Object[] {"BRL""UGX"});

    2.3 根據WSDL生成Client Stub

        這才是Web Service Client的王道,可以訪問任意編寫下的Web Service,將在下一個版本中演示。

    3. 測試

    XFiire很重要的一個特性是提供了無須啟動Web容器也能進行單元測試的能力。

    原理就是利用XFire的JVM模式,以xfire.local://BookService channel而不是http://localhost/service/BookService來訪問服務。

    測試的方式分兩種:

    一種是純服務器角度,不編寫客戶端代碼,以SOAP XML形式發送請求,返回的也是SOAP XML字串,直接對XML進行測試。

    一種是編寫2.1 中Client代碼來進行測試。

    前一種的測試的隔離度較高,而后一種比較簡便。

    3.1 測試基類 

    無論那種方式,都使用Xfire的AbstractXFireSpringTest基類,實現createContext()回調函數。

    protected ApplicationContext createContext() {
          
    return ClassPathXmlApplicationContext(new String[]{"classpath*:applicationContext*.xml"});
     }

    另外測試基類還要完成一個很重要的工作就是要解決Hibernate的LazyLoad問題,做到OpenSession In Test。因此,SpringSide專門封裝了一個XFireTestCase的基類。

    3.2 用Client代碼直接測試

         下文直接用client代碼調用findBooksByCategory方法,得到返回值后進行各種Assert判斷。

         注意和普通client code的兩處區別:servericeURL換成local,factory須加入getXFire()作參數。

    Service serviceModel = new ObjectServiceFactory().create(BookService.class);
      XFireProxyFactory factory 
    = new XFireProxyFactory(getXFire());
      BookService service 
    = (BookService) factory.create(serviceModel, "xfire.local://BookService");
      List list 
    = service.findBooksByCategory("0");
      assertNotNull(list);
      ...

    3.3 純服務端測試

       編寫一段SOAP XML,以任意命名保存,下文以"Java"作參數,調用findBooksByName方法。

    <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
        
    <env:Header/>
        
    <env:Body>
            
    <findBooksByName xmlns="http://www.springside.org.cn">
                
    <in1>Java</in1>
            
    </findBooksByName>
        
    </env:Body>
    </env:Envelope>

       測試代碼調用前面的XML,返回XML Document對象,再用基類提供的一些Assert方法檢查結果:

      Document doc = invokeService("BookService","/org/springside/xfire/BookService.FindBooksByName.xml");
      assertNoFault(doc);
      addNamespace(
    "ss""http://domain.commons.bookstore.springside.org");
      assertValid(
    "//ss:Book/ss:category/ss:descn= "Java Book"", doc);


    posted on 2008-04-24 17:56 々上善若水々 閱讀(1146) 評論(0)  編輯  收藏 所屬分類: WebService

    主站蜘蛛池模板: 亚洲av午夜精品一区二区三区| 国产成人99久久亚洲综合精品| 美女视频黄频a免费| 亚洲欧洲自拍拍偷午夜色无码| 日本免费xxxx| 边摸边吃奶边做爽免费视频99 | 美女扒开屁股让男人桶爽免费| 亚洲午夜久久久久久久久久| 免费可以在线看A∨网站| 国产精品美女久久久免费| 亚洲性无码av在线| 国产精品亚洲视频| 一个人看www在线高清免费看| CAOPORM国产精品视频免费| 亚洲av无码久久忘忧草| 永久亚洲成a人片777777| 好男人www免费高清视频在线| 两个人日本免费完整版在线观看1| 亚洲国产最大av| 亚洲精品成人网站在线观看| 国产精品另类激情久久久免费| 午夜视频在线免费观看| 男女猛烈无遮掩视频免费软件| 亚洲国产中文在线视频| 亚洲国产一二三精品无码| 国产美女精品视频免费观看| 国产成人精品久久免费动漫| 成人网站免费大全日韩国产| 自拍偷自拍亚洲精品播放| 亚洲综合久久久久久中文字幕| 亚洲乳大丰满中文字幕| 国产国产成年年人免费看片| 日韩免费一区二区三区在线播放| 大地影院MV在线观看视频免费| 美女扒开尿口给男人爽免费视频| 在线a亚洲老鸭窝天堂av高清| 亚洲一区精品中文字幕| 久久精品国产亚洲沈樵| 久久精品国产亚洲一区二区三区| 国产免费观看视频| 久久不见久久见中文字幕免费|