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

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

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

    Flier's Sky

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

    寫(xiě)個(gè)短篇開(kāi)個(gè)張,呵呵 :P

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

          在經(jīng)歷過(guò)早年 Delphi, C++, Java 等不成熟環(huán)境中開(kāi)發(fā) WebService 的折磨之后,接觸 ASP.NET 的最大感觸,就是 WebService 的開(kāi)發(fā)門(mén)檻被大大降低了。無(wú)需對(duì) SOAP 或基本架構(gòu)有任何了解,僅需簡(jiǎn)單的定義幾個(gè) Attribute 即可,所有的 dirty work 都由 ASP.NET 在后臺(tái)自動(dòng)完成。例如:
    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}

          而這一巨大的生產(chǎn)力進(jìn)步,現(xiàn)在開(kāi)始在 Java 領(lǐng)域也可直接享用。例如:
     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}

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

          這一神奇效果的幕后英雄就是 codehaus 最新發(fā)布的 xfire 1.0 SOAP 框架。
          與 Axis 等現(xiàn)有實(shí)現(xiàn)相比,xfire 的最大優(yōu)點(diǎn)就是改用 StAX 基于流的 XML 分析引擎,加上其 SOAP 協(xié)議棧實(shí)現(xiàn)上的精巧設(shè)計(jì),能夠帶來(lái)比 Axis 快 2-5 倍的性能提升。具體的性能評(píng)測(cè)數(shù)據(jù),可以參考  一些第三方評(píng)測(cè)結(jié)果 
          而在功能上 xfire 也毫不遜色,其 Features & Goals 里面充滿(mǎn)了各種 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  的詳細(xì)功能對(duì)比,可以參考 Stack Comparison 文檔。

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


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

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

          而對(duì)使用 spring 環(huán)境的開(kāi)發(fā)者來(lái)說(shuō),要提供上述這一系列支持,只需要直接將 xfire-spring 工程中的 fire.xml 文件包括到 applicationContext.xml 中,即可直接獲得完整的 xfire 架構(gòu)。
    1<import resource="classpath:/org/codehaus/xfire/spring/xfire.xml"/>


          不過(guò)相比于通過(guò) xml 文件定義服務(wù)來(lái)說(shuō),我更傾向于直接用 Annotation 方式在代碼級(jí)完成定義。xfire-annotation 提供了對(duì) Java 5 Annotation 和 apache common-attribute 的完整支持。例如上述例子中在 javadoc 里定義的 @@ 標(biāo)簽,就是 用于使用 xdoclet 生成 common-attribute 支持的。
          因?yàn)?nbsp;common-attribute 并非編譯器一級(jí)提供支持,因此要在編譯之前增加一道處理過(guò)程。個(gè)人推薦直接使用 maven 進(jìn)行管理,當(dāng)然也可以在 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 負(fù)責(zé)啟用 maven 的 common-attribute 支持;org.apache.commons.attributes.index.enable 啟用索引模式,生成時(shí)會(huì)自動(dòng)產(chǎn)生一個(gè)索引文件 META-INF/attrs.index;org.apache.commons.attributes.attributepackages 則是預(yù)定義可能用到的 annotations 的包名稱(chēng),以便直接用 WebService 這樣的簡(jiǎn)短名字。
          增加了以上配置后,在 maven 編譯時(shí),會(huì)自動(dòng)增加一個(gè) common-attribute 支持文件的編譯過(guò)程,并在 target/commons-attributes 下生成類(lèi)似 ServerVariables$__attributeRepository.java 的文件,以存儲(chǔ) @@ 標(biāo)簽中指定的 Metadata。在 eclipse 等 IDE 中,我們可以直接把這些目錄添加為源碼目錄。

          而在為了使用 common-attribute 定義的元信息,xfire 提供了 Jsr181HandlerMapping 來(lái)自動(dòng)完成服務(wù)映射支持。
     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>

          因?yàn)?nbsp;xfire 同時(shí)需要支持 Java 5 模式和 common-attribute 模式的元信息,所以對(duì)元信息的獲取被封裝到 annotations.commons.CommonsWebAttributes 和 annotations.jsr181.Jsr181WebAnnotations 中,以便根據(jù)實(shí)際使用進(jìn)行配置。而 xfire 和 xfire.typeMappingRegistry 則是引用前面提到的 xfire.xml 中定義的基礎(chǔ)接口和類(lèi)型映射支持。

          Jsr181HandlerMapping 是從 spring 提供的 ApplicationObjectSupport 上基礎(chǔ)出來(lái)的,它實(shí)現(xiàn)了 ApplicationContextAware 接口,因此會(huì)在 bean 定義被加載完成后,調(diào)用其 setApplicationContext 方法,并進(jìn)而調(diào)用其 initApplicationContext 方法完成初始化。
          Jsr181HandlerMapping.initApplicationContext 方法中,會(huì)遍歷當(dāng)前 ApplicationContext 的所有父容器,調(diào)用 processBeans 方法處理器其 bean 定義。而在 processBeans 中針對(duì)每個(gè) bean,檢查其是否為 singleton 的非抽象對(duì)象,且定義了 WebService Annotation;如果是則構(gòu)造 bean 并以前面提到的方式進(jìn)行注冊(cè)。
    值得注意的是,xfire 1.0 乃至最新 CVS 版本,在這塊的實(shí)現(xiàn)都有一個(gè)嚴(yán)重 bug,沒(méi)有對(duì) abstract bean 進(jìn)行處理。其代碼中直接用 beanFactory.getBean(beanNames[i]) 試圖獲取實(shí)例,如果 bean 是 singleton 的 abstract 模式,則會(huì)導(dǎo)致 spring 拋出異常。可以將其檢測(cè)代碼改成如下方式:
     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 及修復(fù)代碼已提交到 xfire 的 JIRA 上,待進(jìn)一步確認(rèn)。

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

          完成了這些基礎(chǔ)性工作后,剩下的任務(wù)就非常簡(jiǎn)單了。根據(jù) xfire 的 Servlet Setup 文檔,在 web.xml 中增加相關(guān) 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>

          然后就可以通過(guò) ::URL::http://localhost:8080/xfire/services/WeatherService?wsdl  類(lèi)似的方式訪問(wèn) wsdl 或調(diào)用 WebService 了。詳細(xì)的配置請(qǐng)參考 xfire 相關(guān)文檔。
          完整的 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 的話(huà),可以按前面所說(shuō)修改 Jsr181HandlerMapping,并重新編譯 xfire-spring 工程;如果需要提供接口定義服務(wù)的支持,可以按前面所說(shuō)修改 WebService 等,并重現(xiàn)編譯 xfire-annotation 工程。
     
    end.


    只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲福利一区二区| 国产h肉在线视频免费观看| 亚洲日韩av无码中文| 亚洲成年人在线观看| 又粗又硬免费毛片| 在线v片免费观看视频| 午夜老司机永久免费看片| 两个人日本免费完整版在线观看1| 亚洲一区中文字幕在线电影网| 亚洲成AV人片在线观看无码| 亚洲免费无码在线| 国产一区视频在线免费观看| 成人毛片免费观看| 青青在线久青草免费观看| 久久免费看少妇高潮V片特黄| 免费无码又爽又黄又刺激网站| 亚洲国产精品无码久久久秋霞1| 亚洲乱码一二三四区国产| 亚洲一区二区成人| 无码久久精品国产亚洲Av影片| 国产午夜亚洲精品午夜鲁丝片| 免费观看国产小粉嫩喷水| 日韩午夜免费视频| 免费看大黄高清网站视频在线| 免费电视剧在线观看| 在线观看免费人成视频色| 波多野结衣免费在线| 黄色成人免费网站| 999在线视频精品免费播放观看| 67194国产精品免费观看| 蜜桃成人无码区免费视频网站| 小草在线看片免费人成视久网| 久久免费视频观看| 久久国产色AV免费观看| 8x成人永久免费视频| 国产成人yy免费视频| 中字幕视频在线永久在线观看免费| 成人女人A级毛片免费软件| 最近中文字幕无吗免费高清| 在线观看91精品国产不卡免费| 免费国产a国产片高清网站|