花钱的年华

--今天开始成为主站

用户操作
[即时聊天] [发私信] [加为好友]
江南白衣ID:calvinxiu
691020次访问,排名53好友0人,关注者38
calvinxiu的文章
原创 161 篇
翻译 0 篇
转载 0 篇
评论 646 篇
江南白衣的公告

肖桦,江南白衣,
开源项目SpringSide
春天的旁边
发起者

最近评论
calvinxiu:
发版本最痛苦的事情,就是刚发完之后忽然又有了一个比较重要的更新。

推荐大家下载3.0.3.1 (2mb)

1.简化了目录结构,感觉又清爽了不少。
2.消除了最后一块需要逐个Class写配置文件的地方(applicationContext.xml中的sessionFactory的mapping class)。
dreaming:恭喜~
hongyi:还是一头雾水,郁闷,为啥有这么多东东,叫人头大
suncheng_hong:用过appfuse,但springside还没有尝试过。
suncheng_hong:很想尝试一下。
文章分类
    收藏
      相册
      Blog用图
      Friends
      @_@
      Anders小明
      buaawhl
      cac
      canonical
      cctvx1
      david.turing
      femto
      g9
      JohnsonQu
      Michael Chen
      Raimundox
      robbin
      SimonLei
      totodo
      wuyu
      周爱民
      孟岩
      差沙
      庄表伟
      落魄的程序员
      透明
      郁也风
      铁手
      银狐999
      飞云小侠
      存档
      软件项目交易
      订阅我的博客
      XML聚合  FeedSky
      订阅到鲜果
      订阅到Google
      订阅到抓虾
      订阅到BlogLines
      订阅到Yahoo
      订阅到GouGou
      订阅到飞鸽
      订阅到Rojo
      订阅到newsgator
      订阅到netvibes

      原创 XFire 最新生火指南(下) 收藏

      新一篇: Spring2.0,Struts2.0,SpringSide 2.0--SpringSide 2.0M1 Release Notes  | 旧一篇: XFire 最新生火指南(上)

      作者:江南白衣

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

      请先阅读:XFire生火指南(上)

      1. JSR181

           JSR181式通过annotated POJO ,零配置文件的导出Web服务,是BEA倡导的,JavaEE5里的正规方式, XFire作了良好的支持。

           但是,XFire关于JSR181方式的文档还不够清晰,请完整阅读本节以避免其中的数个陷阱。

      1.1 参考文章

      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);

       

      发表于 @ 2006年11月24日 14:57:00|评论(loading...)|编辑

      新一篇: Spring2.0,Struts2.0,SpringSide 2.0--SpringSide 2.0M1 Release Notes  | 旧一篇: XFire 最新生火指南(上)

      评论:没有评论。

      发表评论  


      登录
      Csdn Blog version 3.1a
      Copyright © 江南白衣