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

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

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

    Flier's Sky

    天空,藍色的天空,眼睛看不到的東西,眼睛看得到的東西
    posts - 1, comments - 0, trackbacks - 0, articles - 0

    使用 xfire 快速發布 WebService

    Posted on 2006-03-10 22:56 Flier Lu 閱讀(4352) 評論(0)  編輯  收藏

    寫個短篇開個張,呵呵 :P

    原文:http://www.blogcn.com/User8/flier_lu/blog/29729701.html

          在經歷過早年 Delphi, C++, Java 等不成熟環境中開發 WebService 的折磨之后,接觸 ASP.NET 的最大感觸,就是 WebService 的開發門檻被大大降低了。無需對 SOAP 或基本架構有任何了解,僅需簡單的定義幾個 Attribute 即可,所有的 dirty work 都由 ASP.NET 在后臺自動完成。例如:
    1[ WebService(Description="Common Server Variables",Namespace="http://flier.yeah.net/")]
    2public class ServerVariables: WebService {
    3
    4
    5  [ WebMethod(Description="Obtains the Server Computer Name",EnableSession=false)]
    6  public string GetMachineName() {
    7     return Server.MachineName;
    8  }
       
    9}

          而這一巨大的生產力進步,現在開始在 Java 領域也可直接享用。例如:
     1/**
     2 * Common Server Variables
     3 * 
     4 * @@WebService(name = "ServerVariables", serviceName = "ServerVariables", targetNamespace = "http://flier.yeah.net/")
     5 * @@SOAPBinding(style = SOAPBindingAnnotation.STYLE_RPC)
     6 */

     7public interface ServerVariables
     8{
     9  /**
    10   * @@WebMethod(operationName = "GetMachineName", action="urn:GetMachineName")
    11   * @@.return WebResult("machineName")
    12   */

    13  string GetMachineName();
    14}

          在項目搭建時完成一次性的配置之后,我們絕大多數的工作就是定義 WebService 接口,設定 WebService 的發布方式。然后就是實現此接口并放入 spring 中進行管理,例如:
    1<bean id="serverVariables" class="net.yeah.flier.ws.impl.ServerVariablesImpl" singleton="true">

          這一神奇效果的幕后英雄就是 codehaus 最新發布的 xfire 1.0 SOAP 框架。
          與 Axis 等現有實現相比,xfire 的最大優點就是改用 StAX 基于流的 XML 分析引擎,加上其 SOAP 協議棧實現上的精巧設計,能夠帶來比 Axis 快 2-5 倍的性能提升。具體的性能評測數據,可以參考  一些第三方評測結果 
          而在功能上 xfire 也毫不遜色,其 Features & Goals 里面充滿了各種 big words。

    * Support for important Web Service standards - SOAP, WSDL, WS-I Basic Profile, WS-Addressing, WS-Security, etc.
    * High performance SOAP Stack
    * Pluggable bindings POJOs, XMLBeans, JAXB 1.1, JAXB 2.0, and Castor support
    * JSR 181 API to configure services via Java 5 and 1.4 (Commons attributes JSR 181 syntax)
    * Support for many different transports - HTTP, JMS, XMPP, In-JVM, etc.
    * Embeddable and Intuitive API
    * Spring, Pico, Plexus, and Loom support.
    * JBI Support
    * Client and server stub generation
    * JAX-WS early access support

          與 Axis, Glue 以及 ActiveSOAP  的詳細功能對比,可以參考 Stack Comparison 文檔。

          下面先就 xfire 基礎架構以及與 spring 集成的基本情況大概做一個簡單介紹,回頭有時間再整一個 xfire 與 axis 實現架構的橫向對比。
          與 axis 很相似 xfire 在架構上也可以大概分為 Service, Transport 和 Invoker 三個層面。
          Service 層是 xfire 架構的靜態基礎,負責完成對服務的注冊及其管理。核心的 ServiceRegistry 接口完成對服務自身的生命期管理,如注冊/注銷/獲取等等;而 ServiceFactory 接口則負責從具體的 POJO 類型,生成實現  Service 接口的可被管理的服務代理。
          Transport 層則是 xfire 的外部 IO 處理系統。由 TransportManager 接口對具體的 Transport 接口實現進行管理,默認提供了基于 pipe 的 LocalTransport 和基于 Http 協議的 SoapHttpTransport。理論上可以任意進行擴展,例如 xfire 發布包中還提供了基于 JMS 和 XMPP 的實現。
          Invoker 則是 xfire 的動態調用層,負責在 Transport 層接受到請求后,解析內容、調用合適服務并最終返回 SOAP 封包給調用者。運行時 Invoker 負責維系 Service 和 Transport 之間的聯系。
          因此一個服務的生成和注冊往往類似如下代碼:
    1Service endpoint = serviceFactory.create(clazz); // 根據具體類型創建服務
    2xFire.getServiceRegistry().register(endpoint);     // 向服務管理注冊服務
    3endpoint.setInvoker(new BeanInvoker(bean));             // 設定服務調用模式


          最基本的 XFire 接口,實際上就是 getServiceRegistry() 和 getTransportManager() 的封裝。

          xfire 中另一塊核心的思想,就是其靈活而強大的 binding 機制,負責完成 Java 類型與 SOAP 消息的雙向轉換。xfire 僅僅內建就支持 POJO(Aegis), Castor, JAXB 1.1, JAXB 2.0 和 XMLBeans 多種模式,你可以根據需求選擇從全自動 POJO 生成,到全手工 xsd 文件定義的不同方式。

          而對使用 spring 環境的開發者來說,要提供上述這一系列支持,只需要直接將 xfire-spring 工程中的 fire.xml 文件包括到 applicationContext.xml 中,即可直接獲得完整的 xfire 架構。
    1<import resource="classpath:/org/codehaus/xfire/spring/xfire.xml"/>


          不過相比于通過 xml 文件定義服務來說,我更傾向于直接用 Annotation 方式在代碼級完成定義。xfire-annotation 提供了對 Java 5 Annotation 和 apache common-attribute 的完整支持。例如上述例子中在 javadoc 里定義的 @@ 標簽,就是 用于使用 xdoclet 生成 common-attribute 支持的。
          因為 common-attribute 并非編譯器一級提供支持,因此要在編譯之前增加一道處理過程。個人推薦直接使用 maven 進行管理,當然也可以在 ant 中直接配置 task。maven 1.x 的具體配置方式如下:

    # project.properties for maven 1.x
    #
    org.apache.commons.attributes.enable=true
    org.apache.commons.attributes.index.enable=true
    org.apache.commons.attributes.attributepackages=org.codehaus.xfire.annotations.commons;org.codehaus.xfire.annotations.commons.soap;org.codehaus.xfire.annotations.soap
          其中 org.apache.commons.attributes.enable 負責啟用 maven 的 common-attribute 支持;org.apache.commons.attributes.index.enable 啟用索引模式,生成時會自動產生一個索引文件 META-INF/attrs.index;org.apache.commons.attributes.attributepackages 則是預定義可能用到的 annotations 的包名稱,以便直接用 WebService 這樣的簡短名字。
          增加了以上配置后,在 maven 編譯時,會自動增加一個 common-attribute 支持文件的編譯過程,并在 target/commons-attributes 下生成類似 ServerVariables$__attributeRepository.java 的文件,以存儲 @@ 標簽中指定的 Metadata。在 eclipse 等 IDE 中,我們可以直接把這些目錄添加為源碼目錄。

          而在為了使用 common-attribute 定義的元信息,xfire 提供了 Jsr181HandlerMapping 來自動完成服務映射支持。
     1<bean id="webAnnotations" class="org.codehaus.xfire.annotations.commons.CommonsWebAttributes"/>
     2<bean id="handlerMapping" class="org.codehaus.xfire.spring.remoting.Jsr181HandlerMapping">
     3    <property name="typeMappingRegistry">
     4        <ref bean="xfire.typeMappingRegistry"/>
     5    </property>
     6    <property name="xfire">
     7        <ref bean="xfire"/>
     8    </property>
     9    <property name="webAnnotations">
    10        <ref bean="webAnnotations"/>
    11    </property>
    12</bean>

          因為 xfire 同時需要支持 Java 5 模式和 common-attribute 模式的元信息,所以對元信息的獲取被封裝到 annotations.commons.CommonsWebAttributes 和 annotations.jsr181.Jsr181WebAnnotations 中,以便根據實際使用進行配置。而 xfire 和 xfire.typeMappingRegistry 則是引用前面提到的 xfire.xml 中定義的基礎接口和類型映射支持。

          Jsr181HandlerMapping 是從 spring 提供的 ApplicationObjectSupport 上基礎出來的,它實現了 ApplicationContextAware 接口,因此會在 bean 定義被加載完成后,調用其 setApplicationContext 方法,并進而調用其 initApplicationContext 方法完成初始化。
          Jsr181HandlerMapping.initApplicationContext 方法中,會遍歷當前 ApplicationContext 的所有父容器,調用 processBeans 方法處理器其 bean 定義。而在 processBeans 中針對每個 bean,檢查其是否為 singleton 的非抽象對象,且定義了 WebService Annotation;如果是則構造 bean 并以前面提到的方式進行注冊。
    值得注意的是,xfire 1.0 乃至最新 CVS 版本,在這塊的實現都有一個嚴重 bug,沒有對 abstract bean 進行處理。其代碼中直接用 beanFactory.getBean(beanNames[i]) 試圖獲取實例,如果 bean 是 singleton 的 abstract 模式,則會導致 spring 拋出異常。可以將其檢測代碼改成如下方式:
     1public class Jsr181HandlerMapping extends AbstractUrlHandlerMapping
     2{
     3    private void processBeans(ApplicationContext beanFactory, AnnotationServiceFactory serviceFactory)
     4    {
     5        String[] beanNames = beanFactory.getBeanDefinitionNames();
     6        
     7        ConfigurableApplicationContext ctxt = (ConfigurableApplicationContext) beanFactory;
     8
     9        // Take any bean name or alias that has a web service annotation
    10        for (int i = 0; i < beanNames.length; i++)
    11        {
    12            BeanDefinition def = ctxt.getBeanFactory().getBeanDefinition(beanNames[i]);
    13            
    14            if (!def.isSingleton() || def.isAbstract()) continue;
    15            
    16            //
    17        }

    18    }
        
    19}
        

          此 bug 及修復代碼已提交到 xfire 的 JIRA 上,待進一步確認。

          而在具體對 bean 是否定義服務的判斷上,xfire 1.0 中的支持實際上也是很不完整的。象最上面例子中,由 ServerVariables 定義服務接口,ServerVariablesImpl 中實現服務的方式,直接在 xfire 下是無法使用的。關鍵原因在于 xfire-annotations 工程在定義 WebService 等 annotation 時,沒有指定其可繼承性。
          改進方法也很簡單,在 org.codehaus.xfire.annotations.commons 包的 WebService, WebMethod, WebResult, WebParam 等 annotation 定義中,類一級增加一個 @@org.apache.commons.attributes.Inheritable() 標簽即可。common-attribute 在判斷是否存在某個 annotation 時,會自動將具有 Inheritable 屬性的自定義屬性,繼承到其所有子類。這樣一來就可以很完美的解決通過接口定義服務的問題。此改進也已提交到 xfire 的 JIRA 上,待進一步確認。

          完成了這些基礎性工作后,剩下的任務就非常簡單了。根據 xfire 的 Servlet Setup 文檔,在 web.xml 中增加相關 servlet 的定義,接管 /service/** 或其它 URL。
     1  <servlet>
     2    <servlet-name>XFire</servlet-name>
     3    <display-name>XFire Servlet</display-name>
     4    <servlet-class>
     5        org.codehaus.xfire.transport.http.XFireConfigurableServlet
     6    </servlet-class>
     7    <init-param>
     8      <param-name>config</param-name>
     9      <param-value>services.xml</param-value>
    10    </init-param>
    11  </servlet>
    12
    13  <servlet-mapping>
    14    <servlet-name>XFire</servlet-name>
    15    <url-pattern>/servlet/XFireServlet/*</url-pattern>
    16  </servlet-mapping>
    17
    18  <servlet-mapping>
    19    <servlet-name>XFire</servlet-name>
    20    <url-pattern>/services/*</url-pattern>
    21  </servlet-mapping>

          然后就可以通過 ::URL::http://localhost:8080/xfire/services/WeatherService?wsdl  類似的方式訪問 wsdl 或調用 WebService 了。詳細的配置請參考 xfire 相關文檔。
          完整的 xfire 支持 bean 配置大致如下:
     1<?xml version="1.0" encoding="UTF-8"?>
     2<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
     3<!-- applicationContext-xfire.xml -->
     4<beans>
     5    <import resource="classpath:/org/codehaus/xfire/spring/xfire.xml"/>
     6    
     7    <bean id="webAnnotations" class="org.codehaus.xfire.annotations.commons.CommonsWebAttributes"/>
     8    <bean id="handlerMapping" class="org.codehaus.xfire.spring.remoting.Jsr181HandlerMapping">
     9        <property name="typeMappingRegistry">
    10            <ref bean="xfire.typeMappingRegistry"/>
    11        </property>
    12        <property name="xfire">
    13            <ref bean="xfire"/>
    14        </property>
    15        <property name="webAnnotations">
    16            <ref bean="webAnnotations"/>
    17        </property>
    18    </bean>
    19    
    20    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    21        <property name="urlMap">
    22            <map>
    23                <entry key="/">
    24                    <ref bean="handlerMapping"/>
    25                </entry>
    26            </map>
    27        </property>
    28    </bean>
    29</beans>

          如果需要使用 abstract bean 的話,可以按前面所說修改 Jsr181HandlerMapping,并重新編譯 xfire-spring 工程;如果需要提供接口定義服務的支持,可以按前面所說修改 WebService 等,并重現編譯 xfire-annotation 工程。
     
    end.


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 国产精品久久久久久久久免费| 亚洲免费中文字幕| 九九免费久久这里有精品23| 在线观看无码的免费网站| 中文字幕在线观看亚洲视频| 日本妇人成熟免费中文字幕| 亚洲成a人片在线观看中文app| 2021国产精品成人免费视频| 亚洲偷自精品三十六区| 日韩人妻无码免费视频一区二区三区 | 亚洲欧洲精品久久| 一本岛高清v不卡免费一三区| 亚洲国产成人九九综合| 女人18毛片免费观看| 国产亚洲精品2021自在线| 国产亚洲精aa成人网站| 美女在线视频观看影院免费天天看| 久久精品国产亚洲AV高清热| 永久免费毛片在线播放| 免费手机在线看片| 亚洲精品无码久久久久| 日本免费xxxx| 美女无遮挡免费视频网站| 久久精品国产亚洲综合色| 99视频精品全部免费观看| 亚洲综合久久精品无码色欲| 亚洲国产精品碰碰| 一级毛片在线免费观看| 亚洲国产aⅴ成人精品无吗| 中文字幕中韩乱码亚洲大片| 最近免费中文字幕高清大全 | 久草福利资源网站免费| 亚洲国产精品一区二区三区在线观看 | av在线亚洲欧洲日产一区二区| 午夜精品射精入后重之免费观看 | 91国内免费在线视频| 亚洲av一本岛在线播放| 亚洲小说区图片区另类春色| 无人影院手机版在线观看免费 | 黄色成人免费网站| 四虎国产精品成人免费久久|