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

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

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

    月蝕傳說(shuō)

    浮躁讓人失去理智
    posts - 25, comments - 101, trackbacks - 0, articles - 0
      BlogJava :: 首頁(yè) ::  :: 聯(lián)系 :: 聚合  :: 管理

    1.? 概述


    在前面我已經(jīng)講了一些關(guān)于SCA的基礎(chǔ)知識(shí),使用了本人實(shí)現(xiàn)的一個(gè)SCA容器做為講解示例,9月中旬我把這個(gè)SCA容器做為開(kāi)源項(xiàng)目在Sourceforge.net上立項(xiàng)了,并且正式給這個(gè)SCA容器取名為Balto。

    這一次我將繼續(xù)使用Balto作為示例SCA容器,并講一下SCA程序設(shè)計(jì)中的外部服務(wù)(ExternalService)

    ExternalService
    SCA 中可以被看作是一個(gè) Module 的應(yīng)用出口,它定義了 Module 所要調(diào)用的非 module 內(nèi)部服務(wù)的外部服務(wù)信息,在SCA程序設(shè)計(jì)中的地位舉足輕重。關(guān)于ExternalService的一些基本信息介紹,大家可以看一下我的另一篇文章.


    ExternalService
    雖然描述了外部服務(wù)的信息,但是它需要通過(guò) Binding 來(lái)對(duì)該外部服務(wù)的訪問(wèn)細(xì)節(jié)進(jìn)行描述。關(guān)于 Binding 的更多信息,也可以查看上面所說(shuō)的那篇文章


    我們接下來(lái)將要講的
    ExternalService 都是基于 WebService Binding 的外部服務(wù)。


    2
    .ExternalService的 XML 格式


    ExternalService
    的定義需要寫在 sca.module 文件中,具體格式如下:


    < externalService? name ="xs:NCName" ?override ="sca:OverrideOptions" ? > *

    ????????<in terface .interface-type />


    ????????< binding .binding-type?uri ="xs:anyURI" /> *

    </ externalService >




    ?? 1)????

    先看 externalService 元素,該元素具有兩個(gè)屬性,一個(gè)是 name, 一個(gè)是 override name 是標(biāo)識(shí) externalService 的名稱的,在 ModuleContext 中通過(guò) localService 定位服務(wù)的時(shí)候,是通過(guò) name 屬性所寫的名稱進(jìn)行查詢外部服務(wù)的。


    2)?????
    Interface 元素在之前的《本地服務(wù)》一文中有介紹,主要是指明該外部服務(wù)所對(duì)應(yīng)的接口類型以及位置。一般情況下都使用 java 類型的接口:

    <interface.java interface = “InterfaceClassName”>


    3)?????
    Binding?在下面會(huì)有講解


    3.
    如何去構(gòu)建一個(gè)可用的外部服務(wù)


    既然是外部服務(wù),有很大程度上都是屬于異地節(jié)點(diǎn)上的服務(wù),所以很多情況下我們使用外部服務(wù)都需要一些遠(yuǎn)程調(diào)用的手段對(duì)其進(jìn)行調(diào)用,所以
    ExternalService 也可以直接看作是一個(gè) Remote Service


    我們最常見(jiàn)的遠(yuǎn)程調(diào)用方式有以下幾種:
    RMI EJB Web Service


    外部服務(wù)遠(yuǎn)程調(diào)用的綁定協(xié)議是由
    Binding 元素給出的,目前 SCA 規(guī)范中給除了兩種 Binding ,一種是 SCABinding ,這種 Binding 方式?jīng)]有確切的說(shuō)明;還有一種就是 WebService Binding ,顧名思義,這種 Binding 是基于 WebService 的一種遠(yuǎn)程調(diào)用 Binding


    一旦
    ExternalService 指定了明確的 Binding 方式后,在調(diào)該 ExternalService 指定的接口的方法的時(shí)候, Balto SCA 容器就會(huì)通過(guò) Java 的動(dòng)態(tài)接口代理技術(shù),生成一個(gè)動(dòng)態(tài)的接口代理,然后通過(guò) Binding 的類型以及 ExternalService 的一些信息細(xì)節(jié),在動(dòng)態(tài)接口代理方法中通過(guò) Binding 對(duì)應(yīng)的遠(yuǎn)程調(diào)用協(xié)議(比如 Web Service )進(jìn)行對(duì)應(yīng)的調(diào)用,如圖所示:


    Binding_invoke.jpg


    ?????????????????????????????????????????????圖 1



    生成的不同的

    InvokeHandler 會(huì)根據(jù)協(xié)議需要,解析出 Binding 類型中的信息細(xì)節(jié),然后通過(guò)一些遠(yuǎn)程調(diào)用手段去調(diào)用該外部服務(wù)所在位置的服務(wù)實(shí)體。



    說(shuō)得不明不白的,舉個(gè)

    WebService Binding 的例子會(huì)清楚一些:


    首先我們?cè)?/span> sca.module 文件中寫入:


    < externalService? name ="WeatherProvider" >

    ??
    < interface .java?interface ="net.x.webservice.client.WeatherProvider" />

    ??
    < binding .ws?port ="http://www.webservicex.net/globalweather.asmx?WSDL
    ?????????????????????????????????? #wsdl.endpoint(GlobalWeather/GlobalWeatherSoap)"
    />

    </ externalService >




    這個(gè)

    externalService 的含義是,我們講通過(guò)一個(gè) net.x.webservice.clinet.WeatherProvider 的接口類 ,去調(diào)用一個(gè) web servicec ,而這個(gè) web service 是通過(guò) binding.ws 來(lái)描述的,這個(gè) web service wsdl 的地址是 http://www.webservicex.net/globalweather.asmx?WSDL ,而且該外部服務(wù)調(diào)用的是這個(gè) wsdl 中描述的 GlobalWeather 服務(wù),并且這個(gè)服務(wù)在 wsdl 中的 binding 名是 GlobalWeatherSoap


    也就是說(shuō),Web Service binding的port屬性所需值的格式規(guī)范是這樣的:

    WSDL 1.1 : <WSDL-namespace-URI>#wsdl.endpoint(<service-name>/<port-name>)

    WSDL 2.0 : <WSDL-namespace-URI>#wsdl.endpoint(<service-name>/<endpoint-name>)

    我們可以利用API通過(guò)
    SCA ModuleContext 來(lái)定位這個(gè)外部服務(wù):
    ModuleContext.localService(“WeatherProvider”); 這段代碼將 返回 net.x.webservice.clinet.WeatherProvider 接口。


    不過(guò)這個(gè)接口是沒(méi)有實(shí)現(xiàn)的,因?yàn)槲覀儾豢赡茉诒镜厝?shí)現(xiàn)這個(gè)接口類——我們根本就不知道這個(gè)服務(wù)的具體業(yè)務(wù)邏輯。我們只是通過(guò)這個(gè)接口類的方法調(diào)用,來(lái)確定所需要調(diào)用這個(gè)
    Web Service 所要做的工作。


    根據(jù)上面的圖
    1 可以清楚的知道,Balto SCA容器去定位一個(gè)外部服務(wù)的時(shí)候,當(dāng)?shù)玫搅嗽撨h(yuǎn)程服務(wù)對(duì)應(yīng)的Java接口后,會(huì)生成一個(gè)接口的動(dòng)態(tài)代理,并且,通過(guò)這個(gè)遠(yuǎn)程服務(wù)的Binding信息以及一些調(diào)用方法信息(參數(shù)值,方法名),確定如何利用Axis2 Client去調(diào)用遠(yuǎn)程服務(wù)Binding到的那個(gè)Web Service。下面是動(dòng)態(tài)代理處理用戶調(diào)用方法的簡(jiǎn)要代碼介紹:


    public ?Object?excute(ExternalService?externalService,?Binding?binding,

    ?????????????????????Object?proxy,?Method?method,?Object[]?parameters)?
    ?????????????????????????????????????????????????????? throws
    ?Throwable?{

    ??????????????
    try
    ?{

    ?????????????????????
    if ?(binding? instanceof
    ?WebServiceBinding)?{

    ????????????????????????????WebServiceBinding?wsBinding?
    =
    ?(WebServiceBinding)?binding;

    ?

    ????????????????????????????String?wsdlURI?
    =
    ?wsBinding.getWSDLNameSpaceURI();

    ?

    ????????????????????????????WSDLFactory?wsdlFactory?
    =
    ?WSDLFactoryImpl.newInstance();

    ????????????????????????????WSDLReader?wsdlReader?
    =
    ?wsdlFactory.newWSDLReader();

    ????????????????????????????wsdlReader.setFeature(
    " javax.wsdl.verbose " ,? true
    );

    ????????????????????????????Definition?definition?
    = ?wsdlReader.readWSDL( null
    ,
    ???????????????????????????????????????????????????????????????????????????? ?wsdlURI);

    ????????????????????????????String?webServiceName?
    =
    ?wsBinding.getServiceName();

    ????????????????????????????String?portName?
    =
    ?wsBinding.getPortName();

    ?

    ????????????????????????????……….

    ????????????????????????????
    // ?這是Axis2?Client的調(diào)用代碼


    ????????????????????????????ServiceClient?service?
    = ? new ?ServiceClient();

    ????????????????????????????Options?options?
    = ? new
    ?Options();

    ?

    ????????????????????????????service.setOptions(options);

    ????????????????????????????EndpointReference?targetEPR?
    = ? new
    ?
    ????????????????????????????????????????????????? EndpointReference(serviceURI);

    ????????????????????????????options.setTo(targetEPR);

    ????????????????????????????targetEPR.setAddress(serviceURI);

    ????????????????????????????service.setTargetEPR(targetEPR);

    ??????????????????????????? …….

    ??????????????????????????? // ?根據(jù)返回值類型來(lái)確定調(diào)用方式


    ??????????????????????????? if ?(returnType? == ?Void. class )?{

    ???????????????????????????????????service.sendRobust(omElement);

    ???????????????????????????????????
    return ? null
    ;

    ????????????????????????????}?
    else
    ?{

    ???????????????????????????????????resultElement?
    =
    ?service.sendReceive(omElement);

    ????????????????????????????}

    ?????????????????????????? // ??處理返回的SOAP體


    ??????????????????????????? ………

    ???????}


    ?

    這樣做的目的是為了屏蔽掉開(kāi)發(fā)人員在調(diào)用時(shí)候的一些細(xì)節(jié)處理,開(kāi)發(fā)人員不關(guān)心整個(gè) Web Service 的調(diào)用過(guò)程,只需要像調(diào)用簡(jiǎn)單 java 類一樣調(diào)用即可。


    4
    .實(shí)戰(zhàn)——天氣預(yù)報(bào)


    我們通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)看看如何使用
    Balto SCA 來(lái)進(jìn)行做 ExternalService 示例工程下載


    先考慮這么一個(gè)需求:


    我們?cè)诘卿浺恍┚W(wǎng)頁(yè)的時(shí)候,網(wǎng)頁(yè)上會(huì)顯示出我們所在地當(dāng)前的天氣情況,這種比較個(gè)性化的功能常常能吸引不少網(wǎng)民的眼球。


    問(wèn)題是如何去實(shí)現(xiàn)呢?


    首先,我們登錄到某個(gè)網(wǎng)頁(yè)上的時(shí)候,網(wǎng)站后臺(tái)會(huì)得到我們的訪問(wèn)
    IP 地址,通過(guò)這個(gè)地址是可以確定我們現(xiàn)在所在位置的。

    然后,根據(jù)我們 IP 解析出來(lái)的物理位置,查詢?cè)摰刂纷罱奶鞖庑畔ⅰ?/span>


    大概是這樣去做。


    但是我們?cè)趺慈ソ馕?/span> IP 地址獲得物理位置呢?這種工作一般需要有一個(gè)存儲(chǔ)了大量的 IP 地址到物理地址映射的數(shù)據(jù)庫(kù),一般情況下我們不可能擁有這樣一個(gè)數(shù)據(jù)庫(kù)。更何況,即使得到了物理地址,我們也不可能通過(guò)計(jì)算機(jī)去計(jì)算出當(dāng)前的天氣情況吧??


    雖然我們不能做這些工作,但是在網(wǎng)絡(luò)上存在這大量類似功能的
    Web Service 。我們可以通過(guò)這些免費(fèi)的 Web Service 來(lái)定制這么一個(gè)功能。


    準(zhǔn)備工作:安裝
    Eclipse WTP 1.0 ,下載 Balto_tomcat_0_0_2 :


    我在網(wǎng)上找到了兩個(gè)
    Web Service:


    1.??????
    獲得 IP 地址和物理地址映射的 WebService:

    ???http://ws.fraudlabs.com/ip2locationwebservice.asmx?wsdl


    2.??????
    獲得天氣情況的 Web Service

    ???http://www.webservicex.net/globalweather.asmx?WSDL


    現(xiàn)在需要通過(guò)
    Balto SCA 將這兩個(gè) Web Service 做成 ExternalService


    首先將
    Balto_tomcat_test_0_9 添加到應(yīng)用服務(wù)器中。這里需要說(shuō)明一下, Balto_tomcat_test_0_9 是整合在 tomcat 中的,就是說(shuō)Balto = Tomcat,Balto替換了tomcat的啟動(dòng)Host入口類,所以在 tomcat 啟動(dòng)的時(shí)候 Balto會(huì)去解析部署的web application,當(dāng)發(fā)現(xiàn)該web應(yīng)用是一個(gè)SCA模塊的話,就會(huì)對(duì)這個(gè)web application進(jìn)行解析,并注冊(cè)解析出的相關(guān)SCA模塊信息。當(dāng)然,這些細(xì)節(jié)開(kāi)發(fā)人員是不用關(guān)心的。


    new_batloserver.JPG


    然后新建一個(gè)
    Dynamic Web project ,對(duì)應(yīng)的 Target Runtime 選擇剛設(shè)定好的 Tomcat 服務(wù)器。


    接下來(lái)我們要將
    Web Service WSDL 中描述的復(fù)雜類型數(shù)據(jù)結(jié)構(gòu)生成 Java 靜態(tài)代碼,并且必須是 SDO 類型的。這些復(fù)雜類型是提供給 ExternalService 指定的 Java 接口所需的調(diào)用參數(shù)以及返回結(jié)果使用的,因?yàn)榇蠹叶贾溃?/span> Web Service 在用 SOAP 傳送過(guò)程中, SOAP Body信息體 內(nèi)是采用的 XML 結(jié)構(gòu)文檔,并且在操作執(zhí)行完畢后, Web Service 的返回 SOAP 中,也是利用 XML 對(duì)結(jié)果進(jìn)行描述的,所以 Balto 采用 SDO 作為復(fù)雜類型數(shù)據(jù)結(jié)構(gòu),不僅僅是因?yàn)?/span> SCA 規(guī)范中的要求,更多的是為了更好地序列化、反序列化我們的復(fù)雜類型 (Java2X ML,XML2Java)


    先將上面提到的兩個(gè)
    WSDL 文件下載到本地,然后我們通過(guò)這兩個(gè) WSDL 生成一個(gè) EMF Model


    new_emfmodel.JPG

    ?


    new_emfmodel2.JPG



    完成操作后會(huì)生成一個(gè)新的

    EMF Model 文件,打開(kāi)這個(gè)文件的編輯器,選中根節(jié)點(diǎn),在彈出菜單中選擇 Set SDO Defaults


    set_sdo_defautls.JPG


    ?

    完成上述操作后,再在彈出菜單中選擇 Generate Model Code Eclipse 就會(huì)自動(dòng)生成一套 SDO 的模型代碼,我們還要修改生成的SDO代碼中的XXXPackageImpl的createExtendedMetaDataAnnotations方法,將代碼中描述Element的name不正確的地方修改過(guò)來(lái),并把創(chuàng)建EClass的地方所給出的ImplementClass的地方,將接口類替換成接口的實(shí)現(xiàn)類。上述步驟可以看一下《SCA程序設(shè)計(jì)——遠(yuǎn)程服務(wù),以及實(shí)現(xiàn)遠(yuǎn)程服務(wù)的問(wèn)題和想法》其中有具體說(shuō)明。


    溫馨小貼士: Eclipse?EMF生成的SDO代碼中,用于描述XML的Element名以及對(duì)應(yīng)Java類的XXXPackageImpl類,其中含有一個(gè)createExtendedMetaDataAnnotations方法,這個(gè)方法中描述了對(duì)應(yīng)Java類以及Java類具有的屬性所對(duì)應(yīng)的XML中的Element以及Attribute的名稱。但是一般利用XSD或者WSDL直接生成的SDO代碼中,EMF會(huì)默認(rèn)給出一個(gè)DocumentRoot的類,也就是說(shuō)這個(gè)類才是EMF真正序列化java對(duì)象的根節(jié)點(diǎn),如果不利用DocumentRoot包裝我們的創(chuàng)建的SDO?Java對(duì)象,序列化出來(lái)的XML就會(huì)出現(xiàn)XML名“不正確”的情況,而這種所謂“不正確”情況下Java對(duì)象對(duì)應(yīng)的XML名,是在ExtendedMetaDataAnnotations中給出的。當(dāng)然,上述情況只限于EMF生成的SDO.


    ?

    sdo_codes.JPG?

    ?

    SDO 代碼生成好后,接下來(lái)就需要?jiǎng)?chuàng)建一個(gè)接口類。創(chuàng)建的這個(gè)接口類就是 ExternalService 所要指定的接口類。


    這個(gè)接口類需要和ExternalService在Binding中給出的
    WSDL PortType 具有 相同的操作。使用過(guò) Axis 或者 Axis2 的讀者一定會(huì)聯(lián)想到 Axis 以及 Axis2 提供給開(kāi)發(fā)人員的 WSDL2Java 的工具,這個(gè)工具就是將 WSDL 生成一套 Axis 的客戶端,包括復(fù)雜類型以及所要調(diào)用的 Web Service 對(duì)應(yīng)的客戶端 Stub Balto 目前沒(méi)有提供一個(gè)類似的工具(還在開(kāi)發(fā)當(dāng)中),所以這些工作還需要開(kāi)發(fā)人員自己完成。


    我們現(xiàn)在來(lái)為上面提到的查詢
    IP 對(duì)應(yīng)物理位置的 ip2locationwebservice WSDL 創(chuàng)建一個(gè) Interface 接口類:


    我們給這個(gè)接口類取名為
    IP2LocationWebService ,然后我們查看一個(gè) ip2locationwebservice WSDL 文件,


    大家會(huì)發(fā)現(xiàn)這個(gè)
    WSDL 文件中指定了 3 Binding 方式: POST,GET SOAP Balto 目前只支持 SOAP ,所以我們只關(guān)心和 SOAP Binding 關(guān)聯(lián)的 Port Type Ip2LocationWebServiceSoap 。這個(gè) Port Type 具有一個(gè) Operation (操作) :IP2Location ,該操作的輸入指向是的名為 IP2LocationSoapIn Message ,而這個(gè) Message Element Type 是在 XSD Type 中定義的 IP2Location 類型。看看 WSDL 的就會(huì)很清楚了:


    ip2location_wsdl.JPG


    ?

    所以我們需要給 IP2LocationWebService 定義一個(gè)方法,方法名需要和 WSDL Operation 名同名: IP2Location ,而這個(gè)方法的輸入?yún)?shù)應(yīng)該是剛才所生成的 SDO 中的 IP2LocationTypeImpl (注意: Eclipse 通過(guò) XSD 生成的 SDO 命名規(guī)則是一定的, SDO 模型接口命名規(guī)則是屬性名 +Type SDO 模型接口實(shí)現(xiàn)命名規(guī)則是:屬性名 +TypeImpl ),并且這個(gè)操作的返回值類型是一個(gè) IP2LocationResponseTypeImpl ,代碼如下:


    ?

    public ? interface ?IP2LocationWebService?{

    ???????IP2LocationResponseTypeImpl?IP2Location(IP2LocationTypeImpl?input);

    }

    ?


    這樣一來(lái)我們就為
    ip2locationwebservice 生成好了一個(gè) Java 接口類,這個(gè)類將作為調(diào)用這個(gè) Web Service 的客戶端入口使用。


    根據(jù)上面的介紹,我們可以根據(jù)同樣的步驟為另一個(gè)
    Web Service globalweather 生成同樣的 SDO 模型以及對(duì)應(yīng)的 Java 接口:


    public ? interface ?WeatherProvider?{

    ???????GetCitiesByCountryResponseTypeImpl?
    ????????????????????? GetCitiesByCountry(GetCitiesByCountryTypeImpl?input);

    ???????GetWeatherResponseTypeImpl?GetWeather(GetWeatherTypeImpl?input);

    }


    ?

    折騰了半天,想必各位看官已經(jīng)有點(diǎn)煩了。


    我這里解釋一下,其實(shí)上面的這些步驟都是由于鄙人的
    Balto 目前還沒(méi)有完成 WSDL2Java 工具所致,只能由開(kāi)發(fā)人員手動(dòng)完成。假以時(shí)日,待 Balto 完成了 WSDL2Java 工具后,上述的這些操作講統(tǒng)統(tǒng)不復(fù)存在,只需要開(kāi)發(fā)人員通過(guò)生成向?qū)Вc(diǎn)幾下即可完成上述的復(fù)雜工作。


    完成
    SDO 以及 Java 接口生成后,我們就可以添加 SCA ExternalService 了。


    首先,我們?cè)谶@個(gè)
    Web Project src 下新建一個(gè) sca.module 文件。


    這個(gè)文件是必須存在的,只有它存在
    Balto 才會(huì)認(rèn)為這個(gè) Web porject 是一個(gè) SCA 模塊,否則將不會(huì)對(duì)其進(jìn)行處理。

    看一下 sca.module 文件:


    <? xml?version="1.0"?encoding="ASCII" ?>

    < module? xmlns ="http://www.osoa.org/xmlns/sca/0.9"

    ????xmlns:v
    ="http://www.osoa.org/xmlns/sca/values/0.9"

    ????name
    ="balto_weather_test" >

    ????
    < externalService? name ="IP2LocationWebService" >

    ???????
    < interface .java?interface ="com.fraudlabs.ws.client.IP2LocationWebService"?/>

    ???????
    < binding .ws?port ="http://ws.fraudlabs.com/ip2locationwebservice.asmx?wsdl
    ??????????????????? #wsdl.endpoint(Ip2LocationWebService/Ip2LocationWebServiceSoap)"
    />


    ????
    </ externalService >

    ????
    < externalService? name ="WeatherProvider" >

    ???????
    < interface .java?interface ="net.x.webservice.client.WeatherProvider" />

    ???????
    < binding .ws?port ="http://www.webservicex.net/globalweather.asmx?WSDL
    ???????????????????????????????? #wsdl.endpoint(GlobalWeather/GlobalWeatherSoap)"
    />


    ????
    </ externalService >

    </ module >


    ?

    我們定義了兩個(gè)外部服務(wù),一個(gè)是查詢 IP 對(duì)應(yīng)物理位置的,一個(gè)是通過(guò)物理位置查詢天氣情況的。

    現(xiàn)在我們可以直接使用它們。做一個(gè)測(cè)試使用的 Servlet


    public ? class ?IP2AreaTestServlet? extends ?javax.servlet.http.HttpServlet{

    ???????
    protected ? void
    ?doGet(HttpServletRequest?request,

    ?????????????????????HttpServletResponse?response)?
    throws
    ?ServletException,?
    ????????????????????????????????????????????????????????????? IOException?{

    ??????????????String?serverName?
    =
    ?request.getServerName();

    ??????????????String?localName?
    =
    ?request.getLocalName();

    ??????????????
    // ?獲得訪問(wèn)者的IP地址


    ??????????????String?remote?
    = ?request.getRemoteAddr();

    ??????????????
    // ?找到Ip查詢物理位置的外部服務(wù)


    ??????????????IP2LocationWebService?service1?
    = ?
    ???????????????????????? (IP2LocationWebService)?CurrentModuleContext.getContext().
    ??????????????????????????????????????????????? locateService(
    " IP2LocationWebService "
    );

    ??????????????
    // ?創(chuàng)建一個(gè)輸入?yún)?shù)


    ??????????????IP2LocationType?input?
    = ?IP2LocationFactory.eINSTANCE

    ????????????????????????????.createIP2LocationType();

    ??????????????
    // ?給出IP地址


    ??????????????input.setIP(remote);

    ???????????? ?
    // ?給一個(gè)License.這個(gè)License是該Web?Service提供者給的一個(gè)免費(fèi)版本的License,
    ??????????????// 可能有使用次數(shù)限制
    ??????????????
    // ?如果大家想要一個(gè)新的,可以訪問(wèn)http: // www.fraudlabs.com?


    ??????????????input.setLICENSE(
    " 02-L68K-D95T " );

    ??????????????IP2LocationResponseTypeImpl?result?
    =
    ?service1

    ????????????????????????????.IP2Location((IP2LocationTypeImpl)?input);

    ??????????????IP2LOCATION?location?
    =
    ?result.getIP2LocationResult();

    ??????????????
    // ?找到通過(guò)物理地址獲得天氣情況的外部服務(wù)


    ??????????????WeatherProvider?provider?
    = ?(WeatherProvider)?CurrentModuleContext

    ????????????????????????????.getContext().locateService(
    " WeatherProvider "
    );

    ??????????????GetWeatherType?i?
    =
    ?WebserviceFactory.eINSTANCE.createGetWeatherType();

    ??????????????i.setCityName(location.getCITY());

    ??????????????i.setCountryName(location.getCOUNTRYNAME());

    ??????????????String?result2?
    =
    ?provider.GetWeather((GetWeatherTypeImpl)?i)?
    ??????????????????????????????????????????????????????????? .getGetWeatherResult();
    ??????????????…….

    ???????}
    }


    ?

    整個(gè)調(diào)用過(guò)程就是上面代碼所示,獲得的天氣情況就是 result2 變量中所記錄的。


    這里說(shuō)一下,
    IP2Location Web Service 是需要 License 的,上面所填寫的License是本人申請(qǐng)的一個(gè),可能會(huì)有使用次數(shù)限制,如果大家需要可以去他們的網(wǎng)站注冊(cè)一個(gè)。


    Servlet 中獲得 Remote 是遠(yuǎn)程的 IP 地址,如果這個(gè) Web Project 是在內(nèi)網(wǎng)中被訪問(wèn),那得到的 Remote 地址就會(huì)是內(nèi)網(wǎng)的 IP ,比如 192.168.0.X ,這樣的 IP 地址不一定能查出來(lái)物理地址的,反正我測(cè)試的時(shí)候,得到的 IP 地址是 168.1.100.X ,對(duì)應(yīng)的物理地址是瑞士的某個(gè)城市。


    還有就是
    globalweather 這個(gè) Web Service 的返回結(jié)果很孫子,直接返回一個(gè) XML 結(jié)構(gòu)的字符串,還要我們自己解析,并且給出的 encoding 還有一些問(wèn)題。


    我對(duì)返回的值處理了一下,將結(jié)果打印了出來(lái),訪問(wèn)這個(gè)
    Servlt 后得到以下的結(jié)果:


    weather_result.JPG



    小結(jié)

    SCA ExternalService 可以說(shuō)是一個(gè)Module對(duì)外調(diào)用的接口,它可以屏蔽遠(yuǎn)程傳送的差異性,只要給出正確的BindingSCA容器就會(huì)成功調(diào)用遠(yuǎn)程的服務(wù)。ExternalService統(tǒng)一了SCA模塊對(duì)外訪問(wèn)的方式,一個(gè)實(shí)現(xiàn)較好的SCA容器,將會(huì)支持多種Binding類型,比如EJBJMSRMI等,這樣一來(lái),在設(shè)計(jì)SCA程序的時(shí)候,只需要關(guān)心ExternalService的接口以及對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu),而那些如何去調(diào)用的技術(shù)細(xì)節(jié)將不會(huì)再困擾開(kāi)發(fā)人員。

    前段時(shí)間上網(wǎng)搜索一些關(guān)于SOA的資料,發(fā)現(xiàn)一個(gè)叫X極網(wǎng)的網(wǎng)站引用了我的<SCA程序設(shè)計(jì)——遠(yuǎn)程服務(wù),以及遠(yuǎn)程服務(wù)實(shí)現(xiàn)的一些問(wèn)題和想法>一文,特孫子,沒(méi)有注明轉(zhuǎn)載地址,還TM把標(biāo)題給改了,鄙視一下!所以在這里我只想說(shuō):
    ???????????????????????????? 轉(zhuǎn)載注明原文地址,做人才厚道


    評(píng)論

    # re: SCA程序設(shè)計(jì)——ExternalService的應(yīng)用  回復(fù)  更多評(píng)論   

    2006-11-15 16:02 by FansOne
    沙發(fā)

    # re: SCA程序設(shè)計(jì)——ExternalService的應(yīng)用  回復(fù)  更多評(píng)論   

    2006-11-15 16:04 by lokvin[匿名]
    支持一下,原創(chuàng)

    # re: SCA程序設(shè)計(jì)——ExternalService的應(yīng)用  回復(fù)  更多評(píng)論   

    2006-11-25 21:09 by Dart
    FansOne不夠意思,搶個(gè)沙發(fā)就走人了

    # re: SCA程序設(shè)計(jì)——ExternalService的應(yīng)用  回復(fù)  更多評(píng)論   

    2006-12-17 15:23 by 張如忠
    寫死了binding這不就耦合到一個(gè)固定的服務(wù)器上了嗎,能不能做到不耦合呢?

    # re: SCA程序設(shè)計(jì)——ExternalService的應(yīng)用  回復(fù)  更多評(píng)論   

    2006-12-18 09:52 by Dart
    to 張如忠:

    Binding的信息是在設(shè)計(jì)階段寫出來(lái)的,而且我的理解可能有錯(cuò)誤,Binding的port在SCA規(guī)范中說(shuō)是NameSpace+#wsdl.endpoing,而我直接作為一個(gè)WSDL URL路徑使用了,所以我這種方法不一定正確。況且SCA還有專門的“部署”描述,我想很多和節(jié)點(diǎn)地址有關(guān)的信息(比如你所提到的)應(yīng)該是在部署階段才真正給出來(lái)的。

    # re: SCA程序設(shè)計(jì)——ExternalService的應(yīng)用  回復(fù)  更多評(píng)論   

    2007-05-31 15:20 by 九片棱角的回憶
    支持

    # re: SCA程序設(shè)計(jì)——ExternalService的應(yīng)用  回復(fù)  更多評(píng)論   

    2007-06-08 15:37 by HEDY
    globalweather這個(gè)webservice確實(shí)很孫子!
    我之前也搞過(guò)這個(gè)webservice,沒(méi)差點(diǎn)氣死,返回的是xml,自己解析也就算了,由city查country倒還行,可以解析出來(lái),由city查weather得到的xml怎么解析都出錯(cuò),dom,jdom,dom4j等都用了,沒(méi)成功過(guò)!最后還是自己寫的一個(gè)解析方法,超級(jí)傻!
    主站蜘蛛池模板: 亚洲精品无码Av人在线观看国产| 亚洲综合久久1区2区3区| 四虎国产精品免费视| 免费jjzz在线播放国产| 亚洲午夜福利717| 亚洲美女视频免费| 亚洲精华液一二三产区| 免费国产污网站在线观看不要卡| free哆拍拍免费永久视频| 18级成人毛片免费观看| 午夜无遮挡羞羞漫画免费| 国产a v无码专区亚洲av | 久久国产乱子伦精品免费看| 日韩亚洲国产高清免费视频| 亚洲精品岛国片在线观看| 亚洲最新视频在线观看| 精品一区二区三区免费毛片| 久久免费精彩视频| 青青青国产色视频在线观看国产亚洲欧洲国产综合 | 成人激情免费视频| 亚洲午夜免费视频| 一级做a免费视频观看网站| 精品久久久久久久久免费影院| 国产亚洲精品无码成人| 久久亚洲中文无码咪咪爱| 国产免费AV片在线播放唯爱网| 亚洲中文字幕无码爆乳av中文| 欧洲亚洲国产精华液| 亚洲五月午夜免费在线视频| 精品免费国产一区二区| 亚洲视频一区二区三区四区| 91精品免费不卡在线观看| 国精无码欧精品亚洲一区| 中文字幕在线视频免费观看| 免费在线观看亚洲| 免费看黄福利app导航看一下黄色录像| 一本岛高清v不卡免费一三区| 7777久久亚洲中文字幕蜜桃 | 久久国产免费观看精品3| 亚洲线精品一区二区三区影音先锋| 美女啪啪网站又黄又免费|