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

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

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

    posts - 5, comments - 16, trackbacks - 0, articles - 0

    2006年8月30日

    收藏一篇DLEE老大的文章,里面的話句句說到了我的心坎里。

    為什么我說Struts/WebWork會受到Ajax的威脅呢?有的人可能覺得大家相安無事不是很好,你是不是有神經病故意挑起人民內部矛盾?問題是他們之間確實存在著一些深層的內在矛盾和沖突,這些矛盾才是目前Struts和 WebWork都只能在非常有限的程度上支持Ajax的原因。所以,問題是架構性的,并不是小型的修補或者更好的編程技巧可以徹底解決的。

    傳統的服務器端MVC架構設計(也就是Model2),存在著一個基本的假設就是Web應用的工作流是由一系列的頁面切換構成的。這種架構中的一個View,從語義上來講只能代表一個完整的HTML頁面。整個Web應用的表現層,被劃分成為非常多的頁面的組合。

    而Ajax開發者眼里,Web應用的工作流并不是這樣構成的。Ajax開發者看待Web應用的角度與傳統開發者相比差別非常大。在一個Ajax應用中,只有相對很少的頁面。每個頁面,包括頁面引用CSS樣式、JS腳本,都是一個更小型的Ajax應用。甚至一些功能簡單的Ajax應用,本身僅僅由一個單一的頁面構成。例如一個簡單的RSS閱讀器,還有IBM筆記本上那個獲得天氣預報的桌面。
    按照Ajax in Action,Ajax應用可以分成3種類型:

    1. 以內容為中心的應用,服務器返回的是一段HTML內容。
    2. 以腳本為中心的應用,服務器返回的是一段JS腳本。
    3. 以數據為中心的應用,服務器返回的是一段數據,可以是XML格式、JSON格式或者其他文本格式。
    服務器返回給Ajax應用的3種類型的網絡流量(不稱為數據是與上面第3種Ajax應用相區別),任何一種都不能被簡單地視作傳統MVC架構中的View,因為他們各自所代表的語義與傳統MVC架構中的View的語義是完全不同的。所以可以看出,除了初次交付給瀏覽器一個完整的Ajax應用之外,傳統的MVC架構對于Ajax應用的支持是非常有限的。其實為了給客戶端提供上面3類網絡流量,一個Servlet已經足夠了。DWR、JSON-RPC、Buffalo在服務器端也就是由Servlet實現的,不要求服務器端一定要安裝某種MVC框架。
    上面3類應用,前面的兩類,客戶端JS代碼比較簡單,表現邏輯僅有一部分位于客戶端,大部分仍然位于服務器端,因此傳統的服務器端MVC架構仍然是非常有價值的。但是大家注意第3類Ajax應用,實際上它已經將絕大部分甚至可以將全部的表現邏輯都轉移到客戶端來執行,這個時候服務器端傳統的Web表現層實際上被架空了(皮之不存,毛將焉附?)。而對于Ajax應用來說,雖然近期可能還是以第1類Ajax應用為主(例如,所謂的AHAH技術),但是最有生命力和發展前景的還是第3類Ajax應用。

    自從1999年M$推出IE5.0支持XMLHTTP,可以不刷新頁面以異步方式從服務器獲取數據之后,Web開發的領域就埋下了一顆定時炸彈(6年以后,一個新詞Ajax的出現引爆了這顆炸彈)。Model2最初的設計應該發生在這件大事(現在應該承認,M$做了一件天大的好事)發生之前,其設計師不可能想到異步請求的價值。按照Model2的設計思想直接產生了Struts。但是后來的WebWork在最初設計階段仍然與這個技術失之交臂,這是相當可惜的一件事情。WebWork其實最初設計的時候就可以走的更遠,但是他們只想超越Struts,做一個更好的Model2 MVC開發框架。現在他們再想趕上這班列車已經有點晚了。如果基礎的服務器端MVC架構的價值是可疑的,那么其他圍繞這個架構所開發的基礎架構的價值也同樣是可疑的。

    所以在現在這個時刻,重新正本清源地思考Model2最初的設計,它帶來的Web開發的巨大進步,以及它所存在的不足,是一個非常現實的問題。

    posted @ 2006-09-08 22:16 BennyBao 閱讀(281) | 評論 (0)編輯 收藏

         摘要: 在網上看到了有些同志提到了為Ajax的XMLHttpRequest提供一個對象池,也讀了他們給出的實現代碼。感覺不是特別理想,于是模仿apache的commons中的ObjectPool的思路寫了一個簡單的JavaScript版。望指教: function ...  閱讀全文

    posted @ 2006-09-08 17:47 BennyBao 閱讀(2488) | 評論 (3)編輯 收藏

    在JavaScript可以使用try...catch來進行異常處理。例如:
    try ? {
    ????foo.bar();
    }
    ? catch ?(e)?
    {
    ????alert(e.name?
    + ? " :? " ? +
    ?e.message);
    }

    目前我們可能得到的系統異常主要包含以下6種:
    • EvalError:?raised when an error occurs executing code in eval()
    • RangeError:?raised when a numeric variable or parameter is outside of its valid range
    • ReferenceError: raised when de-referencing an invalid reference
    • SyntaxError: raised when a syntax error occurs while parsing code in eval()
    • TypeError: raised when a variable or parameter is not a valid type
    • URIError: raised when encodeURI() or decodeURI() are passed invalid parameters

    上面的六種異常對象都繼承自Error對象。他們都支持以下兩種構造方法:

    new ?Error();
    new ?Error( " 異常信息 " );

    手工拋出異常的方法如下:

    try ? {
    ????
    throw ? new ?Error( " Whoops! "
    );
    }
    ? catch ?(e)? {
    ????alert(e.name?
    + ? " :? " ? +
    ?e.message);
    }

    如要判斷異常信息的類型,可在catch中進行判斷:

    try ? {
    ????foo.bar();
    }
    ? catch ?(e)?
    {
    ????
    if ?(e? instanceof ?EvalError)?
    {
    ????????alert(e.name?
    + ? " :? " ? +
    ?e.message);
    ????}
    ? else ? if ?(e? instanceof ?RangeError)? {
    ????????alert(e.name?
    + ? " :? " ? +
    ?e.message);
    ????}

    ????
    // ??etc
    }

    Error具有下面一些主要屬性:

    • description: 錯誤描述 (僅IE可用).
    • fileName: 出錯的文件名 (僅Mozilla可用).
    • lineNumber: 出錯的行數 (僅Mozilla可用).
    • message: 錯誤信息 (在IE下同description)
    • name: 錯誤類型.
    • number: 錯誤代碼 (僅IE可用).
    • stack: 像Java中的Stack Trace一樣的錯誤堆棧信息 (僅Mozilla可用).
    因此為了更好的了解錯誤信息我們可以將catch部分改為如下形式:

    try ? {
    ????foo.bar();
    }
    ? catch ?(e)?
    {
    ????
    if ?(browserType? != ?BROWSER_IE)?
    {????????????????????????????
    ????????alert(
    ????????????
    " name:? " ? + ?e.name? +

    ????????????
    " \nmessage:? " ? + ?e.message? +
    ????????????
    " \nlineNumber:? " ? + ?e.lineNumber? +
    ????????????
    " \nfileName:? " ? + ?e.fileName? +
    ????????????
    " \nstack:? " ? + ?e.stack);????????
    ????}

    ????
    else ? {????????????????????
    ????????alert(
    ????????????
    " name:? " ? + ?e.name? +
    ????
    ????????????
    " \nerrorNumber:? " ? + ?(e.number? & ? 0xFFFF )? +

    ????????????
    " \nmessage:? " ? + ?e.message " );????????
    ????}

    }

    JavaScript中的throw命令事實上可以拋出任何對象,并且我們可以在catch接受到此對象。例如:

    try ? {
    ????
    throw ? new ?Date();???? // ?拋出當前時間對象

    }
    ? catch ?(e)? {
    ????alert(e.toLocaleString());????
    // ?使用本地格式顯示當前時間

    }

    posted @ 2006-09-05 17:56 BennyBao 閱讀(2000) | 評論 (1)編輯 收藏

    本文著重討論的是具有RIA特征的Web應用。例如目前比較流行的的Ajax類Web應用。傳統的基于純HTML的Web應用不在本文討論之列。

    隨著Ajax的升溫,開發人員逐漸對Web應用中的各種UI控件和開發框架開始有了越來越濃厚的興趣。目前所知的這方面的控件集或開發框架可以說是并不鮮見。筆者將這些產品大致分為兩個大類:離散控件集型和數據模型驅動型。這兩個詞大家應該很陌生,因為他們都是鄙人自造的。

    離散控件集型 - 此類產品以提供一系列相對獨立的界面控件為主要目的。控件的類型比較全面,例如搭建Web應用常見的各種Grid、Tree、Menu、ToolBar、Window等。不過此類產品一般不會過多的考慮界面中的數據和操作邏輯的封裝,至多只會提供相對簡單的靜態數據綁定*。我認為此類產品的主要出發點是改善Web應用的界面表現能力,同時借助自帶的SDK提供一種更加規范的開發模式。
    目前我所知的大部分產品似乎都屬于這一類別。例如: backbase、qooxdoo、NetAdventage、bindows等。
    Backbase實例中心:
    http://www.backbase.com/demos/explorer

    數據模型驅動型 - 此類產品除了要提供一組比較好用的UI控件集之外,更會提供對界面中數據模型的管理功能。其UI控件以數據敏感控件為主。數據敏感控件可以通過于數據模型的綁定來實現對表現層中數據的展示和控制。這種數據綁定可成為動態數據綁定*。可以說這一類產品的主要出發點除改善Web應用的界面表現能力外,也非常注重提供一種快速開發的模式。
    好的數據模型驅動型的開發框架應該首先包含離散控件集中的各種功能,它事實上是一種相對于單純的UI控件集而言更高層次的抽象。
    o_binding.png
    這種模式其實在以前CS下非常常見,例如VB、Delphi等RAD開發工具提交數據庫應用開發模式都屬于這種類型。不過到了BS下人們似乎都忘記這種開發模式。可能是因為不夠見多識廣,目前筆者所知的此類產品只有dorado。
    dorado的示例中心:
    http://sample.bstek.com

    對于上面提到的兩種數據綁定方式的解釋如下:

    靜態數據綁定 – 是指在控件可以根據指派給他的數據源(往往是XML數據源或簡單的數組)自動的提取并展示其中的數據。這種提取過程是主動完成的,當提取過程結束后控件無法繼續感知數據源中數據的變化。這事實上是從控件到數據源的拉模式(Pull Mode)。

    動態數據綁定 – 是指將控件以觀察者的角色注冊到數據源(往往是經過封裝的私有對象)中。數據源成為被觀察者。當數據源中的數據或狀態發生改變時會主動通知所有觀察者(即綁定的控件),然后再由控件自動提取數據完成展現的更新。這樣一旦綁定建立以后控件就可以實時的體現數據源中的最新變化。如果用戶利用這些控件對數據或狀態做了改變,那么這種改變自然也會通過數據源再實時的通知給所有其它相關的控件。這事實上是從數據源到控件的推模式(Push Mode)。
    ?
    回到關于離散控件集型和數據模型驅動型的討論。這兩種開發框架都有這自己的適用面。筆者認為離散控件集型的開發框架更加適合與一些像論壇這樣更加注重展現的應用。而對于那些具有明顯數據庫應用特性的的Web應用(例如MIS類應用),則數據模型驅動型的開發框架更能發揮它的優勢。
    得出以上結論的原因是我認為數據模型驅動型的開發框架能夠使開發人員將更多的精力投入到界面所需要實現的更能當中,至少在制作頁面的前期階段不必太多的關注界面的表現形式。同時如果能夠將更多的界面操作邏輯封裝到數據模型對象中,就可以保證在后期當最終用戶提出界面的修改要求時,開發人員可以用更小的代價來完成對界面的重構。

    讓我們來具體分析兩個場景:

    場景1:一個用慣了CS應用的用戶要求開發一個界面來維護公司目前擁有的所有書籍。為了方便的完成對所有書籍的CRUD操作,用戶希望以一個Grid控件來完成所有這些操作,同時用戶希望能夠在界面批量的完成一系列C、U、D操作之后一次性的對數據進行保存。每本書籍都有一個由系統自動分配的編碼作為主鍵,因此用戶不需要看到書籍的編碼。
    分析:如果我們現在只有一個離散的Grid控件。要完成上述功能我們還需要做以下一些工作:

  • 由于編碼不在Grid中顯示,因此找到一個辦法能夠管理每本書籍的編碼。
  • 由于客戶端需要緩存用戶的一系列C、U、D操作然后作批量的提交處理,因此必須做一些工作以便記錄下哪些書被修改了、哪些是新增的、哪些被刪除了。
  • 在提交時將所有的數據修改信息抽取出來組裝成可用于提交的格式。

    可見如果使用一個離散的Grid控件來制作這個界面,我們還必須要做不少工作。如果我們能夠選擇一個數據模型驅動型的開發框架,上面提到的很多功能框架中往往已經具備。開發人員要做的往往只是聲明好一個數據模型然后把它跟Grid關聯起來。如果您以前使用過VB或Delphi這一類開發功能,應該不難想像這個過程。

    場景2:想像一個用戶信息的錄入界面,如下圖。使用者需要輸入用戶的身份證,由于什么證的號碼中包含了很多信息,系統完全有可能從其中解析出出生日期和性別這樣的信息。因此為了方便錄入,我們可以讓表單中的出生日期和性別這兩個欄位支持自動填入缺省值的功能,只要用戶錄入了身份證號碼,就可以馬上自動填充上述兩個欄位。

    o_user_form1.png
    ?
    在基于離散控件的編程方式中,我們需要知道身份證、出生日期、性別這三個編輯框的id,并針對他們進行編程。其代碼形式可能如下:

    var?id? = ?inputId.getValue();? // ?獲得身份證號碼
    ?? // ?對身份證進行解析
    inputBrithday.setValue(brithday);? // ?為出生日期設置缺省值
    radioGroupSex.setValue(sex);? // ?為性別設置缺省值

    在基于數據模型驅動型框架的編程方式中,我們并不需要關注界面上擺放了什么控件,只需要知道關注如何操作數據模型對象。其代碼形式可能如下:

    var?id? = ?dmUser.getValue( " id " );? // ?從數據模型(dmUser)中提取身份證號碼
    ?? // ?對身份證進行解析
    dmUser.setValue( " birthday " ,?brithday);? // ?為出生日期設置缺省值
    dmUser.setValue( " sex " ,?sex);? // ?為性別設置缺省值

    可見在這種開發模式中我們的代碼幾乎完全針對數據模型展開,當我們為dmUser中的brithday和sex賦值后,相應的數據敏感控件會立刻自動顯示出這些的數據。這樣的編程模式可以讓代碼有高度的一致性,當我們制作復雜的用戶界面時,可以不需要記住諸多的控件id。
    進一步假設。如果用戶有一天覺得這樣的界面并不方便對多筆數據進行方便的維護,而要求對界面進行如下調整。在刪除原先的表單,利用一個Grid控件來對用戶信息進行維護。
    o_user_form2.png
    如果我們的編程方式是基于離散控件的,那么我們不可避免的要對先前編寫那段代碼做一些調整了。我需要將那段代碼移植到表格當中。
    但是如果我們的編程方式是基于數據模型驅動型框架的,那么我們要做的只是將界面上的表單刪掉,然后在放置一個與現有數據模型綁定的Grid控件。至于那段代碼,它完全不需要做任何變動。

    綜上可見,在MIS類Web應用的表現層開發方面。數據模型驅動型的開發框架可以為開發人員帶來更多的實惠。不知道隨著時間的推移這一類的開發框架會不會豐富起來?

  • posted @ 2006-09-03 00:26 BennyBao 閱讀(2226) | 評論 (9)編輯 收藏

    本文著重討論的是具有AJAX特征的WEB應用表現層的設計模式,特別是如何設計表現層中展現數據的管理模式。同時本文假設應用的用戶界面是操作性和交互性相對較強的MIS類應用,因此其中的部分觀點可能并不適合以內容發布為主的互聯網應用。

    被過度倚重的AJAX

    自打2005年初第一回聽說AJAX以來,這個名詞以飛快的速度傳播,走紅的速度勘比李宇春。AJAX即不是新技術也不是很復雜的技術,它不過是基于WEB的RIA應用的一個操作特性(或技術特性)而已。這一切的發生也許因為是AJAX出現的時機,那正是用戶為了WEB應用那令人不堪的操作性即將抓狂,程序員為了難以實現的頁面操作邏輯而即將崩潰之際。于是AJAX成了BS應用的救命稻草。頹廢的人們看到了希望的曙光。

    不過以鄙人拙見,大家如此熱衷于討論AJAX似乎有點本末倒置了。AJAX本身并不能幫我們上面提到的問題。我們需要應該一套完整的UI組件庫,象VB,DELPHI、PB中的我們曾經用過的那種組件庫,一套易于使用有能夠與各種開發模式的對接的組件庫。當然最好是帶有AJAX特性的組件庫。但是現在我們好像還沒有得到一套令大家都滿意的組件庫,于是我們仍然只能討論AJAX聊以充饑。

    言歸正傳,要設計這樣的一套UI組件庫還有很多障礙需要逾越。

    1.?????? DHTML+JavaScript的組件開發可不像在CS中那樣簡單。
    2.?????? 如何有效的管理展現數據。
    3.?????? 讓性能不在成為瓶頸。
    4.?????? 跨瀏覽器的兼容性。
    5.?????? 好用的設計工具。
    … … …

    瀏覽器端的MVC 將部分表現層邏輯推向前端

    在上面提到的幾個障礙當中我感覺最少被大家提及的就是第二條。拜讀過dlee推薦的<Ajax in Action>,其中提到了在瀏覽器端應用MVC。不過書中只提到了數據與展現的分離,卻并沒有提到如何有效的管理這些用于展現的數據。V自不必想,一定是指運行于瀏覽器中的各種可視化的控件;M應該是指用于展現的數據;而C應當是指介于M和V之間的松耦合的關聯關系。我想“瀏覽器端應用MVC”在其合理性上應該能夠得到大家的共識,如同我們討論Server端的MVC架構模式時一樣,從M的設計開始是我個人的習慣思維,應當也是瀏覽器端MVC中的重中之重。首先設計出一個健壯的表現層中的數據管理模式將為后面的工作打下一個良好基礎。
    ?

    參考文檔 : [原創] Web表現層的Client端設計模式探討

    這里提到的表現層應當是指包含Server端的展現相關的邏輯以及瀏覽器中的邏輯。在傳統的開發方式中表現層邏輯往往只涉及到Server端,而到了Client端已完全變成了HTML+CSS或XML+XSLT毫無設計模式可言。筆者認為隨著技術的發展和AJAX的推動,我們有必要將一部分表現層邏輯推向瀏覽器已進一步增強界面的交互能力。

    或許目前大家設計的WEB頁面還很少需要考慮對展現數據的管理。但是一旦有一天我們擁有了一套好用的UI組件庫,那時我們設計的用戶交互界面的復雜度也就會突破目前我們習慣認為的上限。想像一個稍微有點復雜的場景,如果我們擁有了一個像Excel一樣的可以對任意單元進行實時編輯的Grid組件,用戶可以對其中的數據做任意的增刪改操作,那么我們就必須要考慮一下如何將用戶所填入的數據以合理有效的方式提交回Server端了。
    ?
    CS中的展現數據模型對象

    不過真的要來設計一種在表現層中的數據模型,還真是有點千頭萬縷、無從下手。所以在具體考慮如何管理這些數據之前,我們先來看一看在傳統的CS應用中數據是如何進行管理的,有沒有什么可以借鑒的東西?不約而同的,在這些開發模式中都能找到一種專用的數據模型對象,在VB中它叫ADO.RecordSet、在Delphi中它叫TDataSet、在PB中它叫DataWindow。它們都有一些共同的特點:

    1.?????? 表驅動的結構, 具有當前記錄的概念。
    表驅動的設計模式是由關系型數據庫自然衍生過來的設計方式,這種設計非常有利于用戶對數據的瀏覽和編輯,也符合我們對同結構批量數據進行瀏覽和編輯的一般理解和習慣。
    o_grid.PNG

    2.?????? 控件可直接與數據模型進行綁定。

    數據敏感控件與數據模型進行綁定,并自動的展示、修改或控制其中的數據,這是CS中最常用的一種開發模式。其核心原理就是設計模式中的觀察者模式。數據模型是被觀察者,控件是觀察者。當數據模型中的數據發生變化時,會主動的通知綁定的控件做相應的刷新動作以實時的體現最新的數據。對于支持數據修改或控制操作(例如:翻動記錄的操作)的控件,如果用戶利用其對綁定的數據模型中的數據或狀態做了改變,那么這種改變自然也會實現通知給所有其它相關的控件中。
    o_binding.png?

    但是在現在的
    Java BS
    應用開發過程中我們往往比較少的用到。即使有絕大部分也只是只讀型的綁定。

    3.?????? 弱類型的數據管理方式及列描述對象。
    在上述CS應用中,數據對象大都以類似Map的方式對數據進行管理,而不是像我們在Java中更經常討論的VO、PO的數據描述方式。對弱類型的數據對象而言,真正的數據類型(相當于VO中屬性的類型)是保存在一組列描述對象當中的。
    在Java中我們習慣的讀取和設置屬性的方法往往是:
    employee.getName();?
    ?employee.isMarried();?
    ?…?…?…?
    ?employee.setName(“Henry”);?

    而在CS的開發的代碼中讀取和設置屬性的方法往往是(以ADO.RecordSet為例):
    ?dsEmployee(“name”);?
    ?dsEmployee(“married”);?
    ?…?…?…?
    ?dsEmployee(“name”)??
    = ??“Henry”;?

    4.?????? 都具有一定的數據校驗功能及支持一些與展現相關的屬性。
    數據對象中的列描述對象在描述屬性名和數據類型的同時,往往還包含了其它一些跟顯示和編輯有關的特性,例如:readOnly、format、validator等。以readOnly屬性為例,當我們將數據模型中某個列的readOnly屬性設置為true后,所有與該列相關的數據敏感控件都將變成只讀的狀態。這樣的好處在于開發人員在編寫頁面邏輯時不必過多的考慮頁面上堆砌了那些元素,而之需要關注他要處理怎樣的數據操作邏輯,頁面上大部分的操作邏輯或顯示邏輯都將圍繞數據模型對象而展開。

    5.?????? 支持事件。它們都擁有類似beforeChange、afterChange、beforeDelete、afterDelete這樣的事件,以便于開發人員能夠利用這些事件提供一些簡單的數據校驗或操作邏輯。

    BS中的展現數據模型的初步設想

    CS下的這些數據模型對象在早些年都有著成功的實踐。試想,能不能把這種在CS下的表現層設計模式移植到BS的開發當中呢?不過鑒于BS架構更高的復雜的這個任務并不簡單,按照我的設想經過移植的系統架構大致可能如下:
    o_arch1.png

    圖中數據模型對象被拆分成了兩個部分,即Server端的實例和Client端的實例。當我們要將數據從Server端傳遞到Client端時,系統首先應在Server端構建一個基于Java的數據模型,該數據模型對象的數據取自BO提供的VO。當然,如果Server端原本使用了JSP+Bean的開發模式,數據模型對象也可能直接取自JDBC的ResultSet。而后數據模型對象將利用一套實現已封裝好的規則,將數據以XML等方式輸出到Client端。此時Client端的可視化控件就可以對數據進行瀏覽和操作,如果用戶通過可視化控件對數據做了修改,這些臟數據也將暫時被緩存在Client端數據模型對象中,知道用戶最終點擊了提交按鈕,此系統再利用AJAX機制將數據同步回Server端并執行進一步的后臺處理。
    ?
    看起來我們好像已經有了一個很好的開局!不過筆者認為在BS架構中完全照搬CS中的那套設計思路可能并不是最佳的方案。主要原因在CS中的這些數據模型都是按照表結構驅動的方式設計的,其基本思路類似關系型數據庫中的表。而我們在J2EE的設計模式中更常使用的卻是模型驅動的設計方式。表結構驅動自認有它的有點,易于理解,方便使用。不過他也有一些致命的缺陷,特別是它不能很好的描述數據對象之間的關系,每當我們試圖使用表驅動的模型來描述遞歸,樹,主從關聯這樣數據關系,總是會感覺束手束腳。無疑,基于OO的對象模型的結構是一種更好的數據描述方式,它往往能夠更加準確的、真實的表達數據之間的關系。?

    (未完待續...)?
    ?

    posted @ 2006-08-30 01:55 BennyBao 閱讀(1908) | 評論 (3)編輯 收藏

    主站蜘蛛池模板: 国产福利免费在线观看| 久久久久亚洲AV成人片| 精品国产福利尤物免费| 亚洲视频在线观看地址| 国产成人免费a在线资源| 中文字幕在线免费看线人| 亚洲一卡2卡4卡5卡6卡残暴在线| 又色又污又黄无遮挡的免费视| 日韩免费无码视频一区二区三区| 亚洲国产精品精华液| 亚洲成AV人片天堂网无码| 美女视频黄的全免费视频| 成人A毛片免费观看网站| 亚洲AV综合色区无码二区爱AV| 亚洲午夜精品久久久久久浪潮| 2019中文字幕在线电影免费| 青娱乐在线免费观看视频| 亚洲香蕉免费有线视频| 亚洲精品网站在线观看不卡无广告| 最近中文字幕完整免费视频ww| 日本亚洲高清乱码中文在线观看| 亚洲日韩图片专区第1页| 免费欧洲美女牲交视频| 嫖丰满老熟妇AAAA片免费看| 成人无码精品1区2区3区免费看| 亚洲av产在线精品亚洲第一站| 亚洲人成影院在线无码按摩店| 在线观看免费大黄网站| 97av免费视频| 中文字幕久无码免费久久| 亚洲狠狠婷婷综合久久| 亚洲依依成人精品| 亚洲gv白嫩小受在线观看| 亚洲色欲久久久久综合网| 日本一区免费电影| 亚洲人成网站免费播放| 亚洲一区二区在线免费观看| 九九99热免费最新版| 无人视频在线观看免费播放影院 | 亚洲自偷自偷在线制服| 午夜免费福利在线|