• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            woaidongmao

            文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見諒!~
            隨筆 - 1469, 文章 - 0, 評(píng)論 - 661, 引用 - 0
            數(shù)據(jù)加載中……

            用 JSON 處理緩存

            2006 11 07

            數(shù)據(jù)驗(yàn)證是每個(gè)企業(yè) Web 應(yīng)用程序中最富于挑戰(zhàn)性、日新月異的部分。通常驗(yàn)證元數(shù)據(jù)會(huì)使 JavaScript 模塊中混入服務(wù)器端代碼。在本文中,您將了解如何在服務(wù)器代碼的幫助下將元數(shù)據(jù)緩存在客戶端的優(yōu)秀方法,服務(wù)器代碼將提供 JSONJavaScript Object Notation)形式的字符串化元數(shù)據(jù)。這種方法還允許以類似 Ajax 的方式來處理多值和多組屬性。

             

            每個(gè)應(yīng)用程序的開發(fā)都是為了解決某個(gè)領(lǐng)域的問題。而每個(gè)領(lǐng)域都有自己的一套約束數(shù)據(jù)的規(guī)則和規(guī)范。應(yīng)用程序?qū)⑦@些約束應(yīng)用于數(shù)據(jù)時(shí),約束也就成了驗(yàn)證。所有應(yīng)用程序都需要驗(yàn)證用戶輸入的數(shù)據(jù)。

             

            目前,應(yīng)用程序一般都使用 if-else 語句組合來驗(yàn)證數(shù)據(jù)。這些語句包含了開發(fā)人員硬編碼或通過服務(wù)器端代碼置入的驗(yàn)證數(shù)據(jù)。通常,開發(fā)人員會(huì)使用服務(wù)器端代碼來避免可能導(dǎo)致 JavaServer PageJSP)的細(xì)微數(shù)據(jù)更改。

             

            您可以使用 JavaScript Object NotationJSON)來分組和緩存元數(shù)據(jù),并使用 JavaScript 函數(shù)來訪問元數(shù)據(jù)以驗(yàn)證用戶輸入。

            JavaScript 中有分散的元數(shù)據(jù)時(shí),您無法控制服務(wù)器將評(píng)估多少數(shù)據(jù)以及有多少數(shù)據(jù)傳遞到客戶機(jī)。所有服務(wù)器端代碼片段都將被評(píng)估并發(fā)送到服務(wù)器上。但是,使用 JSON 緩存數(shù)據(jù)時(shí),您可以完全控制向客戶機(jī)發(fā)送的元數(shù)據(jù)量,因?yàn)榉?wù)器端代碼將生成 JSON 形式的元數(shù)據(jù)。這有助于僅將元數(shù)據(jù)發(fā)送至與看到或輸入數(shù)據(jù)的用戶相對(duì)應(yīng)的客戶機(jī)上。

             

            您還可以使用 JSON 來緩存用戶輸入的數(shù)據(jù)。程序緩存數(shù)據(jù)后,將擦除數(shù)據(jù)字段而不是刷新屏幕,這與 Ajax 類似。通過這種方法,用戶可以為同一屬性輸入另一組數(shù)據(jù)。

             

            讓我們一起來探究一下如何使用 JSON 來緩存元數(shù)據(jù)。

             

            JSON 概覽

            使用 JSON(即 JavaScript Object Notation),將以一種特定的字符串形式來表示 JavaScript 對(duì)象。如果將具有這樣一種形式的字符串賦給任意一個(gè) JavaScript 變量,該變量隨后將引用一個(gè)通過指定給該變量的字符串構(gòu)建的對(duì)象。

            例如,假定有一個(gè) policy 對(duì)象,它擁有以下屬性:

            • 計(jì)劃名稱
            • 描述
            • 持續(xù)時(shí)間

            您可以使用以下這種 JSON 形式的字符串來表示該 policy 對(duì)象:

            {"Plane":{"Full Life Cover"}, "Description":{"The best life insurance plan"}, "Term":{"20 years"}}

            如果將此字符串賦給任意一個(gè) JavaScript 變量,則該變量將接受以這種對(duì)象為單位的數(shù)據(jù)。要訪問數(shù)據(jù),請(qǐng)?zhí)峁┬枰L問的屬性所在的路徑。對(duì)于本例,將以上字符串賦給一個(gè)名為 policy 的變量:

            var policy = {"Plane":{"Full Life Cover"}, "Description":{"The best life insurance plan"}, "Term":{"20 years"}}

            將此字符串粘貼到 HTML 頁面的標(biāo)題部分中,然后編寫以下警報(bào):

            alert(policy.Plan)

            如果在任何支持 JavaScript 的瀏覽器中查看此頁面,您都會(huì)看到顯示策略計(jì)劃的警報(bào)。

            示例

            為了演示 JSON 的性能,我們來看一個(gè)有 vehicle 對(duì)象列表的 person 對(duì)象和一個(gè)可以擁有一臺(tái)或多臺(tái)車輛的 person 對(duì)象。每臺(tái)車輛都有以下屬性:

            • 品牌
            • 注冊(cè)碼
            • CC

            瀏覽器 UI 應(yīng)當(dāng)允許用戶添加多臺(tái)具有優(yōu)秀應(yīng)用性能的車輛(通常為固有要求)。每個(gè)屬性都有一些與之關(guān)聯(lián)的限制或驗(yàn)證規(guī)則。您需要指定以下規(guī)則:

            • 品牌名稱
              • 品牌名稱決不能包含數(shù)字。
              • 品牌名稱最多可包含兩個(gè)單詞,中間可加一個(gè)空格。
            • 注冊(cè)碼
              • 注冊(cè)碼必須全都是數(shù)字。
            • CC
              • CC 必須全都是數(shù)字。
              • CC 的最小值為 50,最大值為 5000

            將有三個(gè)與車輛屬性相對(duì)應(yīng)的輸入字段,用戶可在其中輸入信息。接下來,您將看到如何將驗(yàn)證消息分組到 JSON 組中以及如何訪問這些驗(yàn)證消息。

            傳統(tǒng)方法

            現(xiàn)在,當(dāng)用戶輸入的車輛數(shù)據(jù)為 40CC 時(shí),程序必須顯示一條消息,說明輸入的數(shù)據(jù)不在有效的 CC 范圍內(nèi)。您可以用 清單 1 中的代碼簡(jiǎn)單地顯示這條消息:


            清單 1. 傳統(tǒng)代碼

                                           
            if(cc < <%= minCC %> || cc > <%= maxCC %>) {
                 alert(<%= ResourceList.vehicleCCRangeMsg >);
                 }

             

            ResourceList 是一個(gè)服務(wù)器端類,該類中含有關(guān)于車輛的國(guó)際化消息(如 vehicleCCRangeMsg)。這種方法解決問題時(shí)略顯混亂:

            1. 在這種方法中,您將把服務(wù)器端代碼添加到所有客戶端驗(yàn)證函數(shù)中,以檢查條件并顯示消息。
            2. 如果更改了元數(shù)據(jù)和消息(例如服務(wù)器端類或變量)的組織方法,您將會(huì)為更改使用這些元數(shù)據(jù)和消息的客戶機(jī)腳本驗(yàn)證函數(shù)感到十分頭痛。

            JSON 能幫助您做什么?

            如果只需在條件語句和警報(bào)中引用一個(gè) JavaScript 變量而不是服務(wù)器端代碼,您感覺怎么樣?不需要把服務(wù)器端代碼包含在 JavaScript 中,而保存的服務(wù)器端元數(shù)據(jù)和消息中的更改也不會(huì)影響客戶端腳本。這種方法太棒了,是不是?好的,那就是使用基于 JSON 緩存元數(shù)據(jù)時(shí)要做的。

            您將使用一個(gè) JavaScript 對(duì)象把我們的驗(yàn)證數(shù)據(jù)和消息分組到一個(gè)層級(jí)中。然后就像訪問層級(jí)的 JavaScript 對(duì)象一樣訪問這些消息。就是這樣,您已經(jīng)做到了!

            當(dāng)此 JSON 元數(shù)據(jù)對(duì)象就緒后,先前的 JavaScript 代碼片段將類似于 清單 2


            清單 2. 帶有 JSON 元數(shù)據(jù)緩存對(duì)象的警報(bào)

                                           
            if(cc < vehicleValidationsMetadata.CC.minCC || 
                                 cc > vehicleValidationsMetadata.CC.maxCC) {
                 alert(vehicleValidationsMetadata.CC.RangeMessage);
                 }

             

            現(xiàn)在,問題是誰來準(zhǔn)備 JSON 元數(shù)據(jù)對(duì)象?嗯,只有服務(wù)器能做這項(xiàng)工作。服務(wù)器必須生成這個(gè) JSON 對(duì)象,并將其提供給客戶機(jī)(瀏覽器)。一些 Java API 可以幫助您準(zhǔn)備此類(事實(shí)上是任意一類)JSON 對(duì)象。請(qǐng)參閱 參考資料 來查看那些 API

            生成 JSON 元數(shù)據(jù)對(duì)象的典型方法為:

            1. 為實(shí)體及其驗(yàn)證消息準(zhǔn)備一個(gè)層級(jí) Java 對(duì)象。
            2. 對(duì)這些實(shí)體及其驗(yàn)證消息調(diào)用 toString()。這些實(shí)體及其驗(yàn)證消息最有可能把一個(gè) JSON 形式的字符串提供給您。
            3. 將該字符串另存到一個(gè)請(qǐng)求范圍內(nèi)。
            4. JSP 中,獲取該字符串,并將其指派到 JavaScript 變量值的大括號(hào)內(nèi)。

            最終的車輛元數(shù)據(jù)對(duì)象看上去就會(huì)像 清單 3 一樣。


            清單 3. 驗(yàn)證元數(shù)據(jù) JSON 對(duì)象

                                           
            var vehicleValidationsMetadata = {
                 "BrandName":{
                               "CanContainDigits":{false},
                           "MaxWords":{2},
                         "FormatMessage":{"Brand Name cannot contain digits."}, 
                       "WordLimitMessage":{"Brand Name cannot contain more than two words"}
                     },
             "RegistrationNumber":{
                         "CanContainAlphabets":{false},
                          "CanContainDigits":{"true"},
                            "FormatMessage":{"Registration Number can contain only digits."}
                 },
             "CC":{
                          "minCC":{50},
                             "maxCC":{5000},
                            "FormatMessage":
                         {"CC can only be numeric"}, 
                             "RangeMessage":{"CC can be within range of 50 and 5000"}
                 }
             }

             

            服務(wù)器必須生成整個(gè)字符串,第一行和最后一行除外,因?yàn)楫?dāng)前的用戶語言環(huán)境可能要求使用這些消息(并且只有服務(wù)器端代碼能完成這項(xiàng)工作)。在這里,需要注意的一點(diǎn)是此元數(shù)據(jù)對(duì)象僅用于驗(yàn)證車輛。更理想的情況是將 vehicle 元數(shù)據(jù)對(duì)象封裝到 person 元數(shù)據(jù)對(duì)象中。那樣,您就不需要再創(chuàng)建另一個(gè) JavaScript 變量,而只需將該元數(shù)據(jù)對(duì)象包含到 person 元數(shù)據(jù)對(duì)象中。

            在將此元數(shù)據(jù)對(duì)象準(zhǔn)備好后,您可以使用該對(duì)象中的元數(shù)據(jù)和消息來驗(yàn)證數(shù)據(jù)輸入和顯示消息。現(xiàn)在,驗(yàn)證車輛輸入信息的 JavaScript 函數(shù)看上去就會(huì)跟 清單 4 一樣。


            清單 4. 車輛數(shù)據(jù)驗(yàn)證函數(shù)

                                           
            function validateVehicleData() {
                  var brandName = //get brand name from form field
               var registrationNumber = //get Registration Number from form field.
                    var CC = //get CC from form field
               var brandNameTokens = brandName.split(' ');
                    if(brandNameTokens.length > vehicleValidationsMetadata.BrandName.MaxWords) {
                        alert(vehicleValidationMessages.BrandName.WordLimitMessage);
                   }
              .
              .
              .
              if((!vehicleValidationsMetadata.RegistrationNumber.CanContainAlphabets) && 
                                 isNaN(parseInt(registrationNumber))) {
             alert(vehicleValidationMessages.RegistrationNumber.FormatMessage);
             }
              var ccNum = parseInt(CC);
              if(ccNum < vehicleValidationMessages.CC.minCC || 
                                 ccNum > vehicleValidationMessages.CC.maxCC) {
                           alert(vehicleValidationMessages.CC.RangeMessage);
              }
            }

             

            這段代碼看上去是不是好多了?它沒有在 JavaScript 中混入服務(wù)器代碼。如果服務(wù)器端更改存儲(chǔ)元數(shù)據(jù)的方法,則無需再重寫客戶機(jī)腳本。這會(huì)使 JSP 編程人員的日子更輕松些。

            擴(kuò)展客戶端數(shù)據(jù)緩存

            某些 Web 應(yīng)用程序要求用戶為同一個(gè)屬性或?qū)ο筝斎攵鄠€(gè)數(shù)據(jù)。例如,person-vehicle 要求人員為其擁有的每臺(tái)車輛都輸入數(shù)據(jù)。如果此人擁有多臺(tái)車輛,應(yīng)用程序必須允許輸入多臺(tái)車輛的數(shù)據(jù)。我將把此類對(duì)象作為一個(gè) 多組屬性 來引用。如果多組屬性包含任何可以保存多個(gè)數(shù)據(jù)實(shí)例的屬性,我將稱之為 多值屬性。

            現(xiàn)在,多組屬性和多值屬性面臨的問題是必須將數(shù)據(jù)輸入到相同的輸入字段中。那意味著在輸入第二臺(tái)車輛的數(shù)據(jù)之前,必須先保存已輸入的第一臺(tái)車輛的數(shù)據(jù)。您可以通過兩種方法來解決此問題:

            1. 將第一臺(tái)車輛的數(shù)據(jù)發(fā)送到服務(wù)器上并清空輸入字段,以允許用戶輸入下一臺(tái)車輛的數(shù)據(jù)。
            2. 將數(shù)據(jù)緩存到客戶機(jī)上并清空輸入字段,以允許用戶輸入下一臺(tái)車輛的數(shù)據(jù)。

            第一種方法存在的問題是每輸入一臺(tái)車輛的數(shù)據(jù)就需要訪問一次服務(wù)器。這不太好;如果在輸入車輛數(shù)據(jù)后都必須等待服務(wù)器響應(yīng),用戶會(huì)覺得很失望。換種方法,第二種方法的響應(yīng)時(shí)間幾乎為零。用戶可以快速輸入所有車輛數(shù)據(jù)而無需等待。但這里需要考慮的是如何將數(shù)據(jù)存儲(chǔ)到客戶端上。這里有更多方法可將數(shù)據(jù)存儲(chǔ)到客戶機(jī)上:

            1. 在用戶單擊以添加下一臺(tái)車輛的數(shù)據(jù)時(shí)將數(shù)據(jù)以某種形式緩存到隱藏的表字段中。
            2. 將數(shù)據(jù)緩存到一個(gè) JavaScript 對(duì)象中。

            如果要將數(shù)據(jù)存儲(chǔ)到隱藏字段中,您會(huì)為用戶每次輸入新的車輛數(shù)據(jù)都要處理很多隱藏字段或處理隱藏字段數(shù)據(jù)而感到煩惱。這就像有字符串操作就需要頻繁處理字符串一樣。

            但是第二種緩存數(shù)據(jù)的方法提供了一種面向?qū)ο蟮姆椒▉砭彺妗.?dāng)用戶輸入新車輛數(shù)據(jù)時(shí),您將在數(shù)組對(duì)象中創(chuàng)建一個(gè)新元素。不需要任何笨拙的字符串操作。當(dāng)用戶輸完所有車輛數(shù)據(jù)后,您只需構(gòu)建一個(gè)源于該對(duì)象的 JSON 字符串,并通過存儲(chǔ)到某個(gè)隱藏字段中的方式將該字符串發(fā)送至服務(wù)器。這種方法要比第一種方法好得多。

            JSON、數(shù)據(jù)緩存和 Ajax 功能

            當(dāng)使用 JSON 將數(shù)據(jù)緩存到客戶端時(shí),系統(tǒng)將在用戶每次單擊 Add Vehicle 按鈕時(shí)更新數(shù)據(jù)緩存對(duì)象。用于完成此項(xiàng)任務(wù)的 JavaScript 函數(shù)看起來可能跟 清單 5 一樣。


            清單 5. 用于將車輛數(shù)據(jù)添加到 JavaScript 對(duì)象中以進(jìn)行客戶端緩存的函數(shù)

                                           
            function addVehicleData() {
                 var brand = //get vehicle brand;
               var regNo = //get registration number;
                  var cc = //get cc;
             
                  vehicleData[vehicleData.length] = new Object();
                vehicleData[vehicleData.length].brandName = new Object();
              vehicleData[vehicleData.length].brandName = brand;
               //same way update other two properties
             }

             

            在這里,vehicleData 是用于在用戶裝入頁面時(shí)進(jìn)行初始化的 JavaScript 變量。它被初始化為一個(gè)新的數(shù)組對(duì)象,該數(shù)組對(duì)象為空或者含有用戶先前輸入的車輛的車輛元素。

            當(dāng)此函數(shù)將數(shù)據(jù)保存到 JavaScript 對(duì)象中后,程序可以調(diào)用另一個(gè)函數(shù)來清空輸入字段以允許用戶輸入新數(shù)據(jù)。

            在此類應(yīng)用程序中,要求用戶輸入出現(xiàn)次數(shù)最少或出現(xiàn)次數(shù)最多的多組或多值屬性。您可以將這些限制置入 JSON 元數(shù)據(jù)對(duì)象中。在這種情況下,先前的元數(shù)據(jù)對(duì)象將變?yōu)?清單 6 中所示的代碼。


            清單 6. 帶有出現(xiàn)次數(shù)限制的 JSON 元數(shù)據(jù)對(duì)象

                                           
            var vehicleValidationsMetadata = {
                 "MIN_OCC":{0},
                 "MAX_OCC":{10},
                 "MAX_OCC_MSG":{"...."},
                 "MIN_OCC_MSG":{".....},
                 //Everything else is the same
             }

             

            然后,addVehicleData() 函數(shù)將先驗(yàn)證數(shù)據(jù)的出現(xiàn)次數(shù),然后在僅當(dāng)總出現(xiàn)次數(shù)未超出允許的限制時(shí)再將數(shù)據(jù)添加到 JavaScript 對(duì)象中。清單 7 顯示了檢查方法。


            清單 7. JSON 元數(shù)據(jù)對(duì)象限制檢查

                                           
            function addVehicleData() {
               if(vehicleData.length == vehicleValidationsMetadata.MAX_OCC-1) {
                      alert(vehicleValidationsMetadata.MAX_OCC_MSG);
                 }
              //Everything else is the same
            }

             

            當(dāng)用戶提交一個(gè)頁面時(shí)調(diào)用的函數(shù)實(shí)際上用于驗(yàn)證最少的出現(xiàn)次數(shù)。這種方法的最大好處是屏幕不需要刷新以輸入新車輛數(shù)據(jù)。提供此類靜態(tài)屏幕曾經(jīng)是 Ajax 技術(shù)的主要目標(biāo),而您現(xiàn)在用 JSON 也能完成此目標(biāo)。這是關(guān)于更新 JSON 數(shù)據(jù)對(duì)象和通過 JavaScript 處理 HTML DOM 樹的全部?jī)?nèi)容。用戶響應(yīng)時(shí)間是最小值,因?yàn)樗胁僮鲀H在客戶端上執(zhí)行。您可以使用 JSON 來為應(yīng)用程序提供 Ajax 功能。

            當(dāng)用戶單擊 Save 按鈕時(shí),程序?qū)⒄{(diào)用另一個(gè) JavaScript 函數(shù),該函數(shù)將把此 JSON 對(duì)象 字符串化 并將其存儲(chǔ)到程序提交到服務(wù)器上的隱藏表字段中。JSON.js(請(qǐng)參閱 參考資料)有一個(gè) JSON.stringify() 函數(shù),該函數(shù)將獲取 JavaScript 對(duì)象作為輸入并返回字符串輸出。

            服務(wù)器端必須能夠理解 JSON 形式的字符串并生成一個(gè)服務(wù)器端對(duì)象,以處理和保存數(shù)據(jù)。Web 站點(diǎn) http://www.json.org/java/index.html 提供了一個(gè) Java API,該 API 用于處理基于 Java 的應(yīng)用程序的大部分需求。

            結(jié)束語

            您在本文中看到了 JSON 的強(qiáng)大用途。歸結(jié)如下:

            1. JSON 提供了一種優(yōu)秀的面向?qū)ο蟮姆椒?,以便將元?shù)據(jù)緩存到客戶機(jī)上。
            2. JSON 幫助分離了驗(yàn)證數(shù)據(jù)和邏輯。
            3. JSON 幫助為 Web 應(yīng)用程序提供了 Ajax 的本質(zhì)。

             

            參考資料

            學(xué)習(xí)

            • 您可以參閱本文在 developerWorks 全球網(wǎng)站上的 英文原文。
            • json.org:獲取關(guān)于 JavaScript Object Notation 的有用信息、庫和鏈接。
            • Ajax:訪問此信息站點(diǎn),查閱關(guān)于 Ajax 的更多信息以及如何將這些技術(shù)應(yīng)用到 Web 開發(fā)中。
            • developerWorks 中國(guó)網(wǎng)站 Ajax 資源中心:查閱關(guān)于 Ajax 編程模型的一站式信息庫,其中包括文章和教程、論壇、博客、維基、事件和新聞。
            • developerWorks 中國(guó)網(wǎng)站的 Web 專區(qū):了解專門針對(duì) Web 架構(gòu)及開發(fā)的信息,包括下載和產(chǎn)品、開放源碼項(xiàng)目、技術(shù)庫、培訓(xùn)和事件通知,以改進(jìn)工作。
            • 隨時(shí)關(guān)注 developerWorks 技術(shù)活動(dòng)和網(wǎng)絡(luò)廣播 中不斷發(fā)布的技術(shù)講座,通過這些技術(shù)講座可以縮短學(xué)習(xí)周期,并且可以提高高難軟件項(xiàng)目的質(zhì)量和結(jié)果。


            獲得產(chǎn)品和技術(shù)

            • json.js:下載用于 JSON JavaScript。
            • Java API:獲取用于 JSON 的免費(fèi) API。


            討論

             

            關(guān)于作者

            clip_image002

             

            clip_image003

            Bakul Patel IBM 的一名軟件工程師。他參與開發(fā)了一些基于 WebSphere 的產(chǎn)品,并且為研究 Ajax JSON 等新一代 GUI 技術(shù)做了大量工作。他的興趣愛好包括音樂和戶外運(yùn)動(dòng)。

             

            posted on 2009-07-28 11:41 肥仔 閱讀(903) 評(píng)論(0)  編輯 收藏 引用 所屬分類: Web-前臺(tái)

            中文字幕久久亚洲一区| 久久久久免费视频| 亚洲中文字幕无码久久综合网| 国产精品成人久久久久久久| 久久ZYZ资源站无码中文动漫| 7777精品伊人久久久大香线蕉 | 99久久免费国产精品热| 亚洲精品乱码久久久久66| 久久精品国产亚洲av麻豆蜜芽| 日韩美女18网站久久精品| 久久伊人亚洲AV无码网站| 久久久久亚洲精品男人的天堂| 久久中文字幕视频、最近更新| 久久毛片免费看一区二区三区| 久久性精品| 久久久国产99久久国产一| 久久久久久国产a免费观看黄色大片 | 色99久久久久高潮综合影院| 久久99精品久久久久久秒播| 久久久久婷婷| 中文国产成人精品久久亚洲精品AⅤ无码精品 | 伊人久久免费视频| 精品久久人人爽天天玩人人妻| 久久久久亚洲精品无码网址| 亚洲精品无码久久久久AV麻豆| 国产精品久久久久久五月尺| 亚洲AV无码久久| 久久精品国产91久久麻豆自制| 国产成人久久777777| 久久久久综合国产欧美一区二区| 一本色综合久久| 久久精品亚洲一区二区三区浴池 | 久久播电影网| 久久婷婷色综合一区二区| 亚洲va久久久噜噜噜久久狠狠 | 亚洲伊人久久成综合人影院| 亚洲人成精品久久久久| 久久99热狠狠色精品一区| 久久综合狠狠综合久久97色| 亚洲AV无码久久精品色欲| Xx性欧美肥妇精品久久久久久 |