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

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

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

    月蝕傳說

    浮躁讓人失去理智
    posts - 25, comments - 101, trackbacks - 0, articles - 0
      BlogJava :: 首頁 ::  :: 聯系 :: 聚合  :: 管理

    SCA程序設計——ExternalService的應用

    Posted on 2006-11-15 15:23 Dart 閱讀(2736) 評論(7)  編輯  收藏 所屬分類: SCA

    1.? 概述


    在前面我已經講了一些關于SCA的基礎知識,使用了本人實現的一個SCA容器做為講解示例,9月中旬我把這個SCA容器做為開源項目在Sourceforge.net上立項了,并且正式給這個SCA容器取名為Balto。

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

    ExternalService
    SCA 中可以被看作是一個 Module 的應用出口,它定義了 Module 所要調用的非 module 內部服務的外部服務信息,在SCA程序設計中的地位舉足輕重。關于ExternalService的一些基本信息介紹,大家可以看一下我的另一篇文章.


    ExternalService
    雖然描述了外部服務的信息,但是它需要通過 Binding 來對該外部服務的訪問細節進行描述。關于 Binding 的更多信息,也可以查看上面所說的那篇文章


    我們接下來將要講的
    ExternalService 都是基于 WebService Binding 的外部服務。


    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 元素,該元素具有兩個屬性,一個是 name, 一個是 override name 是標識 externalService 的名稱的,在 ModuleContext 中通過 localService 定位服務的時候,是通過 name 屬性所寫的名稱進行查詢外部服務的。


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

    <interface.java interface = “InterfaceClassName”>


    3)?????
    Binding?在下面會有講解


    3.
    如何去構建一個可用的外部服務


    既然是外部服務,有很大程度上都是屬于異地節點上的服務,所以很多情況下我們使用外部服務都需要一些遠程調用的手段對其進行調用,所以
    ExternalService 也可以直接看作是一個 Remote Service


    我們最常見的遠程調用方式有以下幾種:
    RMI EJB Web Service


    外部服務遠程調用的綁定協議是由
    Binding 元素給出的,目前 SCA 規范中給除了兩種 Binding ,一種是 SCABinding ,這種 Binding 方式沒有確切的說明;還有一種就是 WebService Binding ,顧名思義,這種 Binding 是基于 WebService 的一種遠程調用 Binding


    一旦
    ExternalService 指定了明確的 Binding 方式后,在調該 ExternalService 指定的接口的方法的時候, Balto SCA 容器就會通過 Java 的動態接口代理技術,生成一個動態的接口代理,然后通過 Binding 的類型以及 ExternalService 的一些信息細節,在動態接口代理方法中通過 Binding 對應的遠程調用協議(比如 Web Service )進行對應的調用,如圖所示:


    Binding_invoke.jpg


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



    生成的不同的

    InvokeHandler 會根據協議需要,解析出 Binding 類型中的信息細節,然后通過一些遠程調用手段去調用該外部服務所在位置的服務實體。



    說得不明不白的,舉個

    WebService Binding 的例子會清楚一些:


    首先我們在
    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 >




    這個

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


    也就是說,Web Service binding的port屬性所需值的格式規范是這樣的:

    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通過
    SCA ModuleContext 來定位這個外部服務:
    ModuleContext.localService(“WeatherProvider”); 這段代碼將 返回 net.x.webservice.clinet.WeatherProvider 接口。


    不過這個接口是沒有實現的,因為我們不可能在本地去實現這個接口類——我們根本就不知道這個服務的具體業務邏輯。我們只是通過這個接口類的方法調用,來確定所需要調用這個
    Web Service 所要做的工作。


    根據上面的圖
    1 可以清楚的知道,Balto SCA容器去定位一個外部服務的時候,當得到了該遠程服務對應的Java接口后,會生成一個接口的動態代理,并且,通過這個遠程服務的Binding信息以及一些調用方法信息(參數值,方法名),確定如何利用Axis2 Client去調用遠程服務Binding到的那個Web Service。下面是動態代理處理用戶調用方法的簡要代碼介紹:


    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的調用代碼


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

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

    ??????????????????????????? // ?根據返回值類型來確定調用方式


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

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

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

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

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

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

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


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

    ???????}


    ?

    這樣做的目的是為了屏蔽掉開發人員在調用時候的一些細節處理,開發人員不關心整個 Web Service 的調用過程,只需要像調用簡單 java 類一樣調用即可。


    4
    .實戰——天氣預報


    我們通過一個簡單的例子來看看如何使用
    Balto SCA 來進行做 ExternalService 示例工程下載


    先考慮這么一個需求:


    我們在登錄一些網頁的時候,網頁上會顯示出我們所在地當前的天氣情況,這種比較個性化的功能常常能吸引不少網民的眼球。


    問題是如何去實現呢?


    首先,我們登錄到某個網頁上的時候,網站后臺會得到我們的訪問
    IP 地址,通過這個地址是可以確定我們現在所在位置的。

    然后,根據我們 IP 解析出來的物理位置,查詢該地址最近的天氣信息。


    大概是這樣去做。


    但是我們怎么去解析
    IP 地址獲得物理位置呢?這種工作一般需要有一個存儲了大量的 IP 地址到物理地址映射的數據庫,一般情況下我們不可能擁有這樣一個數據庫。更何況,即使得到了物理地址,我們也不可能通過計算機去計算出當前的天氣情況吧??


    雖然我們不能做這些工作,但是在網絡上存在這大量類似功能的
    Web Service 。我們可以通過這些免費的 Web Service 來定制這么一個功能。


    準備工作:安裝
    Eclipse WTP 1.0 ,下載 Balto_tomcat_0_0_2 :


    我在網上找到了兩個
    Web Service:


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

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


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

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


    現在需要通過
    Balto SCA 將這兩個 Web Service 做成 ExternalService


    首先將
    Balto_tomcat_test_0_9 添加到應用服務器中。這里需要說明一下, Balto_tomcat_test_0_9 是整合在 tomcat 中的,就是說Balto = Tomcat,Balto替換了tomcat的啟動Host入口類,所以在 tomcat 啟動的時候 Balto會去解析部署的web application,當發現該web應用是一個SCA模塊的話,就會對這個web application進行解析,并注冊解析出的相關SCA模塊信息。當然,這些細節開發人員是不用關心的。


    new_batloserver.JPG


    然后新建一個
    Dynamic Web project ,對應的 Target Runtime 選擇剛設定好的 Tomcat 服務器。


    接下來我們要將
    Web Service WSDL 中描述的復雜類型數據結構生成 Java 靜態代碼,并且必須是 SDO 類型的。這些復雜類型是提供給 ExternalService 指定的 Java 接口所需的調用參數以及返回結果使用的,因為大家都知道, Web Service 在用 SOAP 傳送過程中, SOAP Body信息體 內是采用的 XML 結構文檔,并且在操作執行完畢后, Web Service 的返回 SOAP 中,也是利用 XML 對結果進行描述的,所以 Balto 采用 SDO 作為復雜類型數據結構,不僅僅是因為 SCA 規范中的要求,更多的是為了更好地序列化、反序列化我們的復雜類型 (Java2X ML,XML2Java)


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


    new_emfmodel.JPG

    ?


    new_emfmodel2.JPG



    完成操作后會生成一個新的

    EMF Model 文件,打開這個文件的編輯器,選中根節點,在彈出菜單中選擇 Set SDO Defaults


    set_sdo_defautls.JPG


    ?

    完成上述操作后,再在彈出菜單中選擇 Generate Model Code Eclipse 就會自動生成一套 SDO 的模型代碼,我們還要修改生成的SDO代碼中的XXXPackageImpl的createExtendedMetaDataAnnotations方法,將代碼中描述Element的name不正確的地方修改過來,并把創建EClass的地方所給出的ImplementClass的地方,將接口類替換成接口的實現類。上述步驟可以看一下《SCA程序設計——遠程服務,以及實現遠程服務的問題和想法》其中有具體說明。


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


    ?

    sdo_codes.JPG?

    ?

    SDO 代碼生成好后,接下來就需要創建一個接口類。創建的這個接口類就是 ExternalService 所要指定的接口類。


    這個接口類需要和ExternalService在Binding中給出的
    WSDL PortType 具有 相同的操作。使用過 Axis 或者 Axis2 的讀者一定會聯想到 Axis 以及 Axis2 提供給開發人員的 WSDL2Java 的工具,這個工具就是將 WSDL 生成一套 Axis 的客戶端,包括復雜類型以及所要調用的 Web Service 對應的客戶端 Stub Balto 目前沒有提供一個類似的工具(還在開發當中),所以這些工作還需要開發人員自己完成。


    我們現在來為上面提到的查詢
    IP 對應物理位置的 ip2locationwebservice WSDL 創建一個 Interface 接口類:


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


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


    ip2location_wsdl.JPG


    ?

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


    ?

    public ? interface ?IP2LocationWebService?{

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

    }

    ?


    這樣一來我們就為
    ip2locationwebservice 生成好了一個 Java 接口類,這個類將作為調用這個 Web Service 的客戶端入口使用。


    根據上面的介紹,我們可以根據同樣的步驟為另一個
    Web Service globalweather 生成同樣的 SDO 模型以及對應的 Java 接口:


    public ? interface ?WeatherProvider?{

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

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

    }


    ?

    折騰了半天,想必各位看官已經有點煩了。


    我這里解釋一下,其實上面的這些步驟都是由于鄙人的
    Balto 目前還沒有完成 WSDL2Java 工具所致,只能由開發人員手動完成。假以時日,待 Balto 完成了 WSDL2Java 工具后,上述的這些操作講統統不復存在,只需要開發人員通過生成向導,點幾下即可完成上述的復雜工作。


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


    首先,我們在這個
    Web Project src 下新建一個 sca.module 文件。


    這個文件是必須存在的,只有它存在
    Balto 才會認為這個 Web porject 是一個 SCA 模塊,否則將不會對其進行處理。

    看一下 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 >


    ?

    我們定義了兩個外部服務,一個是查詢 IP 對應物理位置的,一個是通過物理位置查詢天氣情況的。

    現在我們可以直接使用它們。做一個測試使用的 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();

    ??????????????
    // ?獲得訪問者的IP地址


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

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


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

    ??????????????
    // ?創建一個輸入參數


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

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

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


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

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


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

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

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

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

    ??????????????
    // ?找到通過物理地址獲得天氣情況的外部服務


    ??????????????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();
    ??????????????…….

    ???????}
    }


    ?

    整個調用過程就是上面代碼所示,獲得的天氣情況就是 result2 變量中所記錄的。


    這里說一下,
    IP2Location Web Service 是需要 License 的,上面所填寫的License是本人申請的一個,可能會有使用次數限制,如果大家需要可以去他們的網站注冊一個。


    Servlet 中獲得 Remote 是遠程的 IP 地址,如果這個 Web Project 是在內網中被訪問,那得到的 Remote 地址就會是內網的 IP ,比如 192.168.0.X ,這樣的 IP 地址不一定能查出來物理地址的,反正我測試的時候,得到的 IP 地址是 168.1.100.X ,對應的物理地址是瑞士的某個城市。


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


    我對返回的值處理了一下,將結果打印了出來,訪問這個
    Servlt 后得到以下的結果:


    weather_result.JPG



    小結

    SCA ExternalService 可以說是一個Module對外調用的接口,它可以屏蔽遠程傳送的差異性,只要給出正確的BindingSCA容器就會成功調用遠程的服務。ExternalService統一了SCA模塊對外訪問的方式,一個實現較好的SCA容器,將會支持多種Binding類型,比如EJBJMSRMI等,這樣一來,在設計SCA程序的時候,只需要關心ExternalService的接口以及對應的數據結構,而那些如何去調用的技術細節將不會再困擾開發人員。

    前段時間上網搜索一些關于SOA的資料,發現一個叫X極網的網站引用了我的<SCA程序設計——遠程服務,以及遠程服務實現的一些問題和想法>一文,特孫子,沒有注明轉載地址,還TM把標題給改了,鄙視一下!所以在這里我只想說:
    ???????????????????????????? 轉載注明原文地址,做人才厚道


    評論

    # re: SCA程序設計——ExternalService的應用  回復  更多評論   

    2006-11-15 16:02 by FansOne
    沙發

    # re: SCA程序設計——ExternalService的應用  回復  更多評論   

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

    # re: SCA程序設計——ExternalService的應用  回復  更多評論   

    2006-11-25 21:09 by Dart
    FansOne不夠意思,搶個沙發就走人了

    # re: SCA程序設計——ExternalService的應用  回復  更多評論   

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

    # re: SCA程序設計——ExternalService的應用  回復  更多評論   

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

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

    # re: SCA程序設計——ExternalService的應用  回復  更多評論   

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

    # re: SCA程序設計——ExternalService的應用  回復  更多評論   

    2007-06-08 15:37 by HEDY
    globalweather這個webservice確實很孫子!
    我之前也搞過這個webservice,沒差點氣死,返回的是xml,自己解析也就算了,由city查country倒還行,可以解析出來,由city查weather得到的xml怎么解析都出錯,dom,jdom,dom4j等都用了,沒成功過!最后還是自己寫的一個解析方法,超級傻!
    主站蜘蛛池模板: 可以免费看黄视频的网站| 国产一精品一AV一免费孕妇| 扒开双腿猛进入爽爽免费视频| 亚洲AV天天做在线观看| 国产精品免费大片| 亚洲av不卡一区二区三区| 久久大香伊焦在人线免费| 亚洲乱亚洲乱淫久久| 国产h视频在线观看网站免费| 亚洲国产精品白丝在线观看| 久草视频在线免费| 国产亚洲福利在线视频| 日韩免费无砖专区2020狼| 看一级毛片免费观看视频| 亚洲av中文无码| 免费无码又爽又刺激高潮视频| 日韩精品一区二区亚洲AV观看| 无码乱肉视频免费大全合集| 亚洲爆乳成av人在线视菜奈实| 国产亚洲精品不卡在线| 久久久久久毛片免费播放| 亚洲风情亚Aⅴ在线发布| 亚洲熟妇无码另类久久久| 台湾一级毛片永久免费| 五级黄18以上免费看| 亚洲福利电影在线观看| 亚洲成a人一区二区三区| 57pao国产成视频免费播放| 免费大片av手机看片| 亚洲黄色激情视频| 亚洲人成伊人成综合网久久久| 成人黄动漫画免费网站视频| 一级大黄美女免费播放| 亚洲人成网站日本片| 免费国产一级特黄久久| 无人在线直播免费观看| a级毛片高清免费视频| 亚洲免费闲人蜜桃| 国产精品亚洲玖玖玖在线观看| 黄页网站在线看免费| 在免费jizzjizz在线播|