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

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

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

    posts - 0,  comments - 6,  trackbacks - 0

     在最初的 http 協(xié)議中,沒有上傳文件方面的功能。RFC1867("Form-based File Upload in HTML".)
     http 協(xié)議添加了這個功能??蛻舳说臑g覽器,如 Microsoft IE, Mozila, Opera 等,按照此規(guī)范將用
    戶指定的文件發(fā)送到服務(wù)器。服務(wù)器端的網(wǎng)頁程序,如
     php, asp, jsp 等,可以按照此規(guī)范,解析出用戶
    發(fā)送來的文件。

    2.1客戶端

    簡單來說,RFC1867規(guī)范要求http協(xié)議增加了file類型的input標(biāo)簽,用于瀏覽需要上傳的文件。同時
    要求
    FORM表單的enctype屬性設(shè)置為“multipart/form-data”,method屬性設(shè)置為“post”即可,下面是我們文
    件上傳頁面的表單代碼:

    <form action="<%=request.getContextPath()%>/servlet/SimpleUpload" enctype="multipart/form-data" 
    method
    ="post">

    文本1<input type="text" name="text1" value="文本1"><br>

    文件2<input type="text" name="text2" value="文本2"><br>

    文件1<input type="file" name="file1"><br>

    文件2<input type="file" name="file2"><br>

    文件2<input type="file" name="file3"><br>

    <input type="submit" value="開始上傳">

    </form>

    2.2 服務(wù)器端

    一個文件上傳請求的消息實(shí)體由一系列根據(jù) RFC1867"Form-based File Upload in HTML".)編碼的項(xiàng)目
    (文本參數(shù)和文件參數(shù))組成。自己編程來解析獲取這些數(shù)據(jù)是非常麻煩的,還需要了解
    RFC1867規(guī)范對請
    求數(shù)據(jù)編碼的相關(guān)知識。
    FileUpload 可以幫助我們解析這樣的請求,將每一個項(xiàng)目封裝成一個實(shí)現(xiàn)了FileItem
    接口的對象,并以列表的形式返回。所以,我們只需要了解FileUploadAPI如何使用即可,不用管它們的底
    層實(shí)現(xiàn)。讓我們來看一個簡單文件上傳處理代碼:

    DiskFileItemFactory factory = new DiskFileItemFactory();

    ServletFileUpload uploader = new ServletFileUpload(factory);

    List<FileItem> list = uploader.parseRequest(request);

    if (item.isFormField()){

    // 處理普通表單域

    String field = item.getFieldName();//表單域名

    String value = item.getString("GBK");

    else {

    //將臨時文件保存到指定目錄

    String fileName = item.getName();//文件名稱

    String filepath = "您希望保存的目錄/" + fileName;

    item.write(new File(filepath));//執(zhí)行保存

    }

        怎么樣?簡單吧!下面我們來繼續(xù)了解一些必須了解的API

    FileItem接口

    org.apache.commons.fileupload.disk.DiskFileItem實(shí)現(xiàn)了FileItem接口,用來封裝單個表單字段元素的
    數(shù)據(jù)。通過調(diào)用
    FileItem 定義的方法可以獲得相關(guān)表單字段元素的數(shù)據(jù)。我們不需要關(guān)心DiskFileItem的具
    體實(shí)現(xiàn),在程序中可以采用
    FileItem接口類型來對DiskFileItem對象進(jìn)行引用和訪問。FileItem類還實(shí)現(xiàn)了
    Serializable接口,以支持序列化操作。

    下圖是一個文件上傳表單:



    上圖表單提交的http數(shù)據(jù)包的內(nèi)容:

    POST /demo/servlet/SimpleUpload HTTP/1.1

    Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/msword, 
    application/vnd.ms-excel, application/vnd.ms-powerpoint, */*

    Referer: http://127.0.0.1:8080/demo/simpleUpload.jsp

    Accept-Language: zh-cn

    Content-Type: multipart/form-data; boundary=---------------------------7da1772c5504c6

    UA-CPU: x86

    Accept-Encoding: gzip, deflate

    User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727)

    Host: 127.0.0.1:8080

    Content-Length: 184423

    Connection: Keep-Alive

    Cache-Control: no-cache

    Cookie: JSESSIONID=BD8E58E5BAD9B559C0262077FB5E0B4E

    -----------------------------7da1772c5504c6

    Content-Disposition: form-data; name="text1"

    鄭州蜂鳥科技有限公司

    -----------------------------7da1772c5504c6

    Content-Disposition: form-data; name="text2"

    申林

    -----------------------------7da1772c5504c6

    Content-Disposition: form-data; name="file1"; filename="C:\Documents and Settings\All Users\
    Documents\My Pictures\示例圖片\Blue hills.jpg"

    Content-Type: image/pjpeg

    大量二進(jìn)制數(shù)據(jù)內(nèi)容,無法復(fù)制 …….

    -----------------------------7da1772c5504c6

    Content-Disposition: form-data; name="file2"; filename="C:\Documents and Settings\All Users\
    Documents\My Pictures\示例圖片\
    Sunset.jpg"

    Content-Type: image/pjpeg

    大量二進(jìn)制數(shù)據(jù)內(nèi)容,無法復(fù)制 …….

    -----------------------------7da1772c5504c6

    Content-Disposition: form-data; name="file3"; filename="C:\Documents and Settings\All Users\
    Documents\My Pictures\示例圖片\
    Water lilies.jpg"

    Content-Type: image/pjpeg

    大量二進(jìn)制數(shù)據(jù)內(nèi)容,無法復(fù)制 …….

    從第一行,也就是請求行,我們可以看出這是一個post請求。在請求頭部部分,我們可以看到這樣
    一個頭部信息:

    Content-Type: multipart/form-data; boundary=---------------------------7da1772c5504c6

    其中紅色部分說明該請求是一個multipart/form-data類型即多媒體類型的請求。藍(lán)色部分boundary的值
    定義了一個字段分隔界線。在消息體部分可以看出每個表單字段元素?cái)?shù)據(jù)之間采用字段分隔界線進(jìn)行分
    割,兩個分隔界線間的內(nèi)容稱為一個分區(qū),每個分區(qū)中的內(nèi)容包括兩部分,一部分是對表單字段元素進(jìn)
    行描述的描述頭,另外一部分是表單字段元素的主體內(nèi)容。 

    通過對比描述頭,我們可以很容易區(qū)分文本字段和文件字段。不管是文件字段還是文本字段,都有
    name屬性,即該字段作為一個表單域的名字。而文件字段還有filename,即上傳文件本身的名字。另外,
    還有
    conten-type屬性用于指明文件的類型。

    每一個表單字段,不管它是文本還是文件,都被封裝成 FileItem 對象,我們稱之為文件項(xiàng),當(dāng)文件
    項(xiàng)數(shù)據(jù)內(nèi)容尺寸小于
    DiskFileItemFactory 的sizeThreshold 屬性設(shè)置的臨界值時,直接保存在內(nèi)存中;否則,
    將數(shù)據(jù)流以臨時文件的形式,保存在 
    DiskFileItemFactory 的 repository 屬性指定的臨時目錄中。臨時文件
    名形如“
    upload_00000005(八位或八位以上的數(shù)字).tmp”。
    FileItem類內(nèi)部提供了維護(hù)臨時文件名中的
    數(shù)值不重復(fù)的機(jī)制,以保證了臨時文件名的唯一性。另外,如何保證臨時文件能被及時清除,釋放寶貴
    的系統(tǒng)資源,是非常重要的,我們將在后面講解。 

    FileItem類常用的方法:

    1.  boolean isFormField()方法

    isFormField方法用于判斷FileItem類對象封裝的數(shù)據(jù)是一個普通文本表單字段,還是一個文件表單字
    段,如果是普通表單字段則返回true,否則返回false。

    2.  String getName()方法 

    getName方法用于獲得文件上傳字段中的文件名,即表單字段元素描述頭中的filename屬性值,如“C:\Documents and Settings\All Users\Documents\My Pictures\示例圖片\Sunset.jpg”。如果FileItem類對象對
    應(yīng)的是普通表單字段,
    getName方法將返回null。即使用戶沒有通過網(wǎng)頁表單中的文件字段傳遞任何
    文件,但只要設(shè)置了文件表單字段的name屬性,瀏覽器也會將文件字段的信息傳遞給服務(wù)器,
    只是文件名和文件內(nèi)容部分都為空,但這個表單字段仍然對應(yīng)一個
    FileItem對象,此時,
    getName
    方法返回結(jié)果為空字符串
    "",讀者在調(diào)用Apache文件上傳組件時要注意考慮這個情況。

    注意:上面的數(shù)據(jù)包是通過IE提交,所以是完整的路徑和名稱。如 
    C:\Documents and Settings\All Users\Documents\My Pictures\示例圖片\
    Sunset.jpg。如果是其它瀏覽
    器,如火狐和Chromium,則僅僅是名字,沒有路徑,如
    Sunset.jpg。

    3.  String getFieldName()方法

    getFieldName方法用于返回表單字段元素描述頭的name屬性值,也是表單標(biāo)簽name屬性的值。例
    如“
    name=file1”中的“file1”。

    4.  void write(File file)方法

    write方法用于將FileItem對象中保存的主體內(nèi)容保存到某個指定的文件中。如果FileItem對象中的主
    體內(nèi)容是保存在某個臨時文件中,該方法順利完成后,臨時文件有可能會被清除。該方法也可將普通
    表單字段內(nèi)容寫入到一個文件中,但它主要用途是將上傳的文件內(nèi)容保存在本地文件系統(tǒng)中。

    5.  String getString()方法

    getString方法用于將FileItem對象中保存的數(shù)據(jù)流內(nèi)容以一個字符串返回,它有兩個重載的定義形式:

    public java.lang.String getString()

    public java.lang.String getString(java.lang.String encoding)

    throws java.io.UnsupportedEncodingException

    前者使用缺省的字符集編碼將主體內(nèi)容轉(zhuǎn)換成字符串,后者使用參數(shù)指定的字符集編碼將主體內(nèi)容
    轉(zhuǎn)換成字符串。
    如果在讀取普通表單字段元素的內(nèi)容時出現(xiàn)了中文亂碼現(xiàn)象,請調(diào)用第二個
    getString方法,并為之傳遞正確的字符集編碼名稱。

    6.  String getContentType()方法

    getContentType 方法用于獲得上傳文件的類型,即表單字段元素描述頭屬性“Content-Type”的值,
    如“
    image/jpeg”。如果FileItem類對象對應(yīng)的是普通表單字段,該方法將返回null。

    7.  boolean isInMemory()方法

    isInMemory方法用來判斷FileItem對象封裝的數(shù)據(jù)內(nèi)容是存儲在內(nèi)存中,還是存儲在臨時文件中,
    如果存儲在內(nèi)存中則返回true,否則返回false

    8.  void delete()方法

    delete方法用來清空FileItem類對象中存放的主體內(nèi)容,如果主體內(nèi)容被保存在臨時文件中,
    delete方法將刪除該臨時文件。

    盡管當(dāng)FileItem對象被垃圾收集器收集時會自動清除臨時文件,但及時調(diào)用delete方法可以更早的
    清除臨時文件,釋放系統(tǒng)存儲資源。另外,當(dāng)系統(tǒng)出現(xiàn)異常時,仍有可能造成有的臨時文件被永久
    保存在了硬盤中。

    9.  InputStream getInputStream()方法

        以流的形式返回上傳文件的數(shù)據(jù)內(nèi)容。

    10. long getSize()方法

    返回該上傳文件的大?。ㄒ宰止?jié)為單位)。

    DiskFileItemFactory

    將請求消息實(shí)體中的每一個項(xiàng)目封裝成單獨(dú)的DiskFileItem (FileItem接口的實(shí)現(xiàn)對象的任務(wù)
    由 
    org.apache.commons.fileupload.FileItemFactory 接口的默認(rèn)實(shí)現(xiàn) 
    org.apache.commons.fileupload.disk.DiskFileItemFactory 來完成。當(dāng)上傳的文件項(xiàng)目比較小時,直接保
    存在內(nèi)存中
    (速度比較快),比較大時,以臨時文件的形式,保存在磁盤臨時文件夾(雖然速度
    慢些,但是內(nèi)存資源是有限的)。

    屬性

    1) public static final int DEFAULT_SIZE_THRESHOLD :將文件保存在內(nèi)存還是
    磁盤臨時文件夾的默認(rèn)臨界值,值為10240,即10kb

    2) private File repository:用于配置在創(chuàng)建文件項(xiàng)目時,當(dāng)文件項(xiàng)目大于臨界值時使
    用的臨時文件夾,默認(rèn)采用系統(tǒng)
    默認(rèn)的臨時文件路徑,可以通過系統(tǒng)屬性 java.io.tmpdir 
    獲取。如下代碼:

    System.getProperty("java.io.tmpdir");

    3) private int sizeThreshold用于保存將文件保存在內(nèi)存還是磁盤臨時文件夾的臨界值

    構(gòu)造方法

    1) public DiskFileItemFactory():采用默認(rèn)臨界值和系統(tǒng)臨時文件夾構(gòu)造文件項(xiàng)工廠對象。

    2) public DiskFileItemFactory(int sizeThreshold,File repository):采用參數(shù)指定臨界值和系統(tǒng)臨時
    文件夾構(gòu)造文件項(xiàng)工廠對象。

    FileItem createItem() 方法

    根據(jù)DiskFileItemFactory相關(guān)配置將每一個請求消息實(shí)體項(xiàng)目創(chuàng)建 成DiskFileItem 實(shí)例,并返回。
    該方法從來不需要我們親自調(diào)用,FileUpload組件在解析請求時內(nèi)部使用。

    void setSizeThreshold(int sizeThreshold)

    Apache文件上傳組件在解析上傳數(shù)據(jù)中的每個字段內(nèi)容時,需要臨時保存解析出的數(shù)據(jù),以便
    在后面進(jìn)行數(shù)據(jù)的進(jìn)一步處理(保存在磁盤特定位置或插入數(shù)據(jù)庫)。因?yàn)?/font>Java虛擬機(jī)默認(rèn)可以使
    用的內(nèi)存空間是有限的,超出限制時將會拋出“
    java.lang.OutOfMemoryError”錯誤。如果上傳的文件
    很大,例如800M的文件,在內(nèi)存中將無法臨時保存該文件內(nèi)容,Apache文件上傳組件轉(zhuǎn)而采用臨時
    文件來保存這些數(shù)據(jù);但如果上傳的文件很小,例如
    600個字節(jié)的文件,顯然將其直接保存在內(nèi)存中
    性能會更加好些。

    setSizeThreshold方法用于設(shè)置是否將上傳文件已臨時文件的形式保存在磁盤的臨界值(以字節(jié)
    為單位的
    int值),如果從沒有調(diào)用該方法設(shè)置此臨界值,將會采用系統(tǒng)默認(rèn)值10KB。對應(yīng)的
    getSizeThreshold() 方法用來獲取此臨界值。

    void setRepository(File repository)

    setRepositoryPath方法用于設(shè)置當(dāng)上傳文件尺寸大于setSizeThreshold方法設(shè)置的臨界值時,將文件以
    臨時文件形式保存在磁盤上的存放目錄。有一個對應(yīng)的獲得臨時文件夾的 File getRespository() 方法。

    注意:當(dāng)從沒有調(diào)用此方法設(shè)置臨時文件存儲目錄時,默認(rèn)采用系統(tǒng)默認(rèn)的臨時文件路徑,可以
    通過系統(tǒng)屬性 
    java.io.tmpdir 獲取。如下代碼:

    System.getProperty("java.io.tmpdir");

    Tomcat系統(tǒng)默認(rèn)臨時目錄為“<tomcat安裝目錄>/temp/”。

    ServletFileUpload 類

    org.apache.commons.fileupload.servlet.ServletFileUpload類是Apache文件上傳組件處理文件上傳的
    核心高級類(所謂高級就是不需要管底層實(shí)現(xiàn),暴露給用戶的簡單易用的接口)。

    使用其 parseRequest(HttpServletRequest) 方法可以將通過表單中每一個HTML標(biāo)簽提交的數(shù)據(jù)封裝
    成一個
    FileItem對象,然后以List列表的形式返回。使用該方法處理上傳文件簡單易用。

    如果你希望進(jìn)一步提高新能,你可以采用 getItemIterator 方法,直接獲得每一個文件項(xiàng)的數(shù)據(jù)輸
    入流,對數(shù)據(jù)做直接處理。

    在使用ServletFileUpload對象解析請求時需要根據(jù)DiskFileItemFactory對象的屬性 sizeThreshold(臨
    界值)和
    repository(臨時目錄) 來決定將解析得到的數(shù)據(jù)保存在內(nèi)存還是臨時文件中,如果是臨時
    文件,保存在哪個臨時目錄中?。所以,我們需要在進(jìn)行解析工作前構(gòu)造好
    DiskFileItemFactory對象,
    通過ServletFileUpload對象的構(gòu)造方法或
    setFileItemFactory()方法設(shè)置 ServletFileUpload對象的
    fileItemFactory屬性。

    ServletFileUpload繼承結(jié)構(gòu):

    java.lang.Object

    |org.apache.commons.fileupload.FileUploadBase

         |org.apache.commons.fileupload.FileUpload

    |org.apache.commons.fileupload.servlet.ServletFileUpload

    構(gòu)造方法:

    1) public ServletFileUpload():構(gòu)造一個未初始化的實(shí)例,需要在解析請求之前先調(diào)用
    setFileItemFactory()方法設(shè)置 fileItemFactory屬性。

    2) public ServletFileUpload(FileItemFactory fileItemFactory):構(gòu)造一個實(shí)例,并根據(jù)參數(shù)
    指定的
    FileItemFactory 對象,設(shè)置 fileItemFactory屬性。

    ServletFileUpload類常用方法:

    1. public void setSizeMax(long sizeMax)方法

    setSizeMax方法繼承自FileUploadBase類,用于設(shè)置請求消息實(shí)體內(nèi)容(即所有上傳數(shù)據(jù))的最大
    尺寸限制,
    以防止客戶端惡意上傳超大文件來浪費(fèi)服務(wù)器端的存儲空間。其參數(shù)以字節(jié)為單位的
    long型數(shù)字
    。

    在請求解析的過程中,如果請求消息體內(nèi)容的大小超過了setSizeMax方法的設(shè)置值,將會拋出
    FileUploadBase內(nèi)部定義的SizeLimitExceededException異常(FileUploadException的子類)。如:

    org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException
    the request was rejected because its size (1649104) exceeds the configured 
    maximum (153600)

    該方法有一個對應(yīng)的讀方法:public long getSizeMax()方法。

    2. public void setFileSizeMax(long fileSizeMax)方法

    setFileSizeMax方法繼承自FileUploadBase類,用于設(shè)置單個上傳文件的最大尺寸限制,以防止客戶
    端惡意上傳超大文件來浪費(fèi)服務(wù)器端的存儲空間。其
    參數(shù)以字節(jié)為單位的long型數(shù)字。該方法有一個
    對應(yīng)的讀方法:public long geFileSizeMax()方法。

    在請求解析的過程中,如果單個上傳文件的大小超過了setFileSizeMax方法的設(shè)置值,將會拋出
    FileUploadBase內(nèi)部定義的FileSizeLimitExceededException異常(FileUploadException的子類)。如:

    org.apache.commons.fileupload.FileUploadBase$FileSizeLimitExceededException: The field file1 exceeds its
     maximum permitted size of 51200 characters.

    3. public List parseRequest(javax.servlet.http.HttpServletRequest req)

    parseRequest 方法是ServletFileUpload類的重要方法,它是對HTTP請求消息體內(nèi)容進(jìn)行解析的入口
    方法。
    解析出FORM表單中的每個字段的數(shù)據(jù),并將它們分別包裝成獨(dú)立的FileItem對象,然后將這
    FileItem對象加入進(jìn)一個List類型的集合對象中返回。

    該方法拋出FileUploadException異常來處理諸如文件尺寸過大、請求消息中的實(shí)體內(nèi)容的類型不
    是“
    multipart/form-data”、IO異常、請求消息體長度信息丟失等各種異常。每一種異常都是
    FileUploadException的一個子類型。

    4. public FileItemIterator getItemIterator(HttpServletRequest request)

    getItemIterator方法和parseRequest 方法基本相同。但是getItemIterator方法返回的是一個迭代
    器,該迭代器中保存的不是
    FileItem對象,而是FileItemStream 對象,如果你希望進(jìn)一步提高新能,
    你可以采用 
    getItemIterator 方法,直接獲得每一個文件項(xiàng)的數(shù)據(jù)輸入流,做底層處理;如果性能不
    是問題,你希望代碼簡單,則采用
    parseRequest方法即可。
     

    5. public stiatc boolean isMultipartContent(HttpServletRequest req)

    isMultipartContent方法方法用于判斷請求消息中的內(nèi)容是否是“multipart/form-data”類型,是則返
    true,否則返回false。
    isMultipartContent方法是一個靜態(tài)方法,不用創(chuàng)建ServletFileUpload類的實(shí)例對
    象即可被調(diào)用。

    6. getFileItemFactory()setFileItemFactory(FileItemFactory)方法

    方法繼承自FileUpload類,用于設(shè)置和讀取fileItemFactory屬性。

    7. public void setProgressListener(ProgressListener pListener)

    設(shè)置文件上傳進(jìn)度監(jiān)聽器。關(guān)于監(jiān)聽器的具體內(nèi)容,將在后面學(xué)習(xí)。該方法有一個對應(yīng)的讀取
    方法:ProgressListener getProgressListener()

    8.public void setHeaderEncoding()方法

    在文件上傳請求的消息體中,除了普通表單域的值是文本內(nèi)容以外,文件上傳字段中的文件路
    徑名也是文本,在內(nèi)存中保存的是它們的某種字符集編碼的字節(jié)數(shù)組,Apache文件上傳組件在讀取
    這些內(nèi)容時,必須知道它們所采用的字符集編碼,才能將它們轉(zhuǎn)換成正確的字符文本返回。

    setHeaderEncoding方法繼承自FileUploadBase類,用于設(shè)置上面提到的字符編碼。如果沒有設(shè)置,
    則對應(yīng)的讀方法g
    etHeaderEncoding()方法返回null,將采用HttpServletRequest設(shè)置的字符編碼,如果
    HttpServletRequest的字符編碼也為null,則采用系統(tǒng)默認(rèn)字符編碼??梢酝ㄟ^一下語句獲得系統(tǒng)默認(rèn)
    字符編碼:

    System.getProperty("file.encoding"));

    好,到這里我們學(xué)習(xí)了主要的一些API,足夠我們來完成一個簡單文件上傳的功能了,下一章,
    我們將一起來編寫一個文件上傳應(yīng)用程序。

     

    鄭州蜂鳥科技有限公司 申林 QQ:38185398  鄭州軟件開發(fā)興趣小組群:38236716

    學(xué)軟件開發(fā),到蜂鳥科技!超強(qiáng)的師資力量 、完善的課程體系 、超低的培訓(xùn)價(jià)格 、真實(shí)的企業(yè)項(xiàng)目。

    地址:鄭州市文化路豐產(chǎn)路口東50米豐產(chǎn)路21號SOHO世紀(jì)城西塔20樓F
    電話:0371-63839606  手機(jī):13838505572(申老師) 13673990036 (許老師)
    QQ: 1073422643  1群:47614738 2群:108157678 
    網(wǎng)址:www.ntcsoft.com

    posted on 2010-09-03 23:29 whistler 閱讀(24571) 評論(1)  編輯  收藏


    FeedBack:
    # re: Java 文件上傳組件 Apache Commons FileUpload 應(yīng)用指南(二)——FileUpload如何工作?
    2012-04-19 11:40 | sopping
    解決了我一個很大的困惑,我的一些input域沒有加上name屬性,在server端解析時就直接略過了,后面才發(fā)現(xiàn)。原來是這樣:
    -----------------------------------------
    不管是文件字段還是文本字段,都有name屬性,即該字段作為一個表單域的名字。
    -----------------------------------------  回復(fù)  更多評論
      

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    <2012年4月>
    25262728293031
    1234567
    891011121314
    15161718192021
    22232425262728
    293012345

    留言簿(2)

    我參與的團(tuán)隊(duì)

    文章檔案(22)

    搜索

    •  

    最新評論

    主站蜘蛛池模板: 产传媒61国产免费| 亚洲三级在线免费观看| 久久精品亚洲综合| 曰批视频免费30分钟成人| 美女裸免费观看网站| 亚洲国产精品久久久久网站| 亚洲国产精品张柏芝在线观看 | 久久青青草原亚洲AV无码麻豆 | 亚洲午夜理论片在线观看| 亚洲AV无码一区二三区 | 亚洲精品你懂的在线观看| 999国内精品永久免费观看| 日韩毛片免费一二三| 亚洲视频一区二区在线观看| 99久久免费精品视频| 亚洲成av人片在www鸭子| 久久久久亚洲精品美女| 免费高清资源黄网站在线观看| 欧美激情综合亚洲一二区| 国产成人免费ā片在线观看| 无码精品人妻一区二区三区免费| 亚洲成人影院在线观看| 一级毛片免费在线观看网站| 亚洲AV色吊丝无码| 国产aⅴ无码专区亚洲av| 国产成人啪精品视频免费网| 18禁止观看免费私人影院| 在线成人精品国产区免费| 国产精品无码亚洲一区二区三区| 国产一精品一aⅴ一免费| 五月婷婷在线免费观看| 亚洲人成人伊人成综合网无码 | 亚洲小说图区综合在线| 国产乱子影视频上线免费观看| 国产V片在线播放免费无码| 亚洲不卡av不卡一区二区| 亚洲国产电影av在线网址| 人妻在线日韩免费视频| 亚洲国产成人无码av在线播放| 国产乱子伦精品免费无码专区 | 亚洲福利一区二区精品秒拍|