色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Spring Boot+Filter實(shí)現(xiàn)Gzip壓縮超大json對象

jf_ro2CN3Fa ? 來源:芋道源碼 ? 作者:芋道源碼 ? 2022-12-01 10:18 ? 次閱讀


1. 業(yè)務(wù)背景

是這樣的,業(yè)務(wù)背景是公司的內(nèi)部系統(tǒng)有一個廣告保存接口,需要ADX那邊將投放的廣告數(shù)據(jù)進(jìn)行保存供后續(xù)使用。 廣告數(shù)據(jù)大概長這樣:

  • adName是廣告名字
  • adTag是廣告渲染的HTML代碼,超級大數(shù)據(jù)庫中都是用text類型來存放的,我看到最大的adTag足足有60kb大小…
{
"adName":"",
"adTag":""
}

因此,對與請求數(shù)據(jù)那么大的接口我們肯定是需要作一個優(yōu)化的否則太大的數(shù)據(jù)傳輸有以下幾個弊端:

  • 占用網(wǎng)絡(luò)帶寬,而有些云產(chǎn)品就是按照帶寬來計費(fèi)的,間接浪費(fèi)了錢
  • 傳輸數(shù)據(jù)大導(dǎo)致網(wǎng)絡(luò)傳輸耗時

為了克服這幾個問題團(tuán)隊中的老鳥產(chǎn)生一個想法:

請求廣告保存接口時先將Json對象字符串進(jìn)行GZIP壓縮,那請求時傳入的就是壓縮后的數(shù)據(jù),而GZIP的壓縮效率是很高的,因此可以大大減小傳輸數(shù)據(jù),而當(dāng)數(shù)據(jù)到達(dá)廣告保存接口前再將傳來的數(shù)據(jù)進(jìn)行解壓縮,還原成JSON對象就完成了整個GZIP壓縮數(shù)據(jù)的請求以及處理流程。

其實(shí)這樣做也存在著弊端:

  • 請求變復(fù)雜了

    • 接口調(diào)用方那邊需要對數(shù)據(jù)進(jìn)行壓縮
    • 接口執(zhí)行方那邊需要對拿到的數(shù)據(jù)進(jìn)行解壓
  • 需要額外占用更多的CPU計算資源

  • 可能會影響到原有的其他接口

對于以上幾點(diǎn)基于我們公司當(dāng)前的業(yè)務(wù)可以這樣解決:

  • 對與需要占用而外的CPU計算資源來說,公司的內(nèi)部系統(tǒng)屬于IO密集型應(yīng)用,因此用一些CPU資源來換取更快的網(wǎng)絡(luò)傳輸其實(shí)是很劃算的
  • 使用過濾器在請求數(shù)據(jù)到達(dá)Controller之前對數(shù)據(jù)進(jìn)行解壓縮處理后重新寫回到Body中,避免影響Controller的邏輯,代碼零侵入
  • 而對于改造接口的同時是否會影響到原來的接口這一點(diǎn)可以通過 HttpHeader 的Content-Encoding=gzip屬性來區(qū)分是否需要對請求數(shù)據(jù)進(jìn)行解壓縮

那廢話少說,下面給出實(shí)現(xiàn)方案

基于 Spring Boot + MyBatis Plus + Vue & Element 實(shí)現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

  • 項目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 視頻教程:https://doc.iocoder.cn/video/

2. 實(shí)現(xiàn)思路

前置知識:
  • Http 請求結(jié)構(gòu)以及Content-Encoding 屬性
  • gzip壓縮方式
  • Servlet Filter
  • HttpServletRequestWrapper
  • Spring Boot
  • Java 輸入輸出流

實(shí)現(xiàn)流程圖:

e6600140-711c-11ed-8abf-dac502259ad0.png
核心代碼:

創(chuàng)建一個SpringBoot項目,先編寫一個接口,功能很簡單就是傳入一個Json對象并返回,以模擬將廣告數(shù)據(jù)保存到數(shù)據(jù)庫

/**
*@ClassName:ProjectController
*@Authorzhangjin
*@Date2022/3/2420:41
*@Description:
*/
@Slf4j
@RestController
publicclassAdvertisingController{

@PostMapping("/save")
publicAdvertisingsaveProject(@RequestBodyAdvertisingadvertising){
log.info("獲取內(nèi)容"+advertising);
returnadvertising;
}
}

/**
*@ClassName:Project
*@Authorzhangjin
*@Date2022/3/2420:42
*@Description:
*/
@Data
publicclassAdvertising{
privateStringadName;
privateStringadTag;
}

編寫并注冊一個攔截器

/**
*@ClassName:GZIPFilter
*@Authorzhangjin
*@Date2022/3/260:36
*@Description:
*/
@Slf4j
@Component
publicclassGZIPFilterimplementsFilter{

privatestaticfinalStringCONTENT_ENCODING="Content-Encoding";
privatestaticfinalStringCONTENT_ENCODING_TYPE="gzip";

@Override
publicvoidinit(FilterConfigfilterConfig)throwsServletException{
log.info("initGZIPFilter");
}

@Override
publicvoiddoFilter(ServletRequestservletRequest,ServletResponseservletResponse,FilterChainfilterChain)throwsIOException,ServletException{
longstart=System.currentTimeMillis();
HttpServletRequesthttpServletRequest=(HttpServletRequest)servletRequest;

StringencodeType=httpServletRequest.getHeader(CONTENT_ENCODING);
if(CONTENT_ENCODING_TYPE.equals(encodeType)){
log.info("請求:{}需要解壓",httpServletRequest.getRequestURI());
UnZIPRequestWrapperunZIPRequestWrapper=newUnZIPRequestWrapper(httpServletRequest);
filterChain.doFilter(unZIPRequestWrapper,servletResponse);
}
else{
log.info("請求:{}無需解壓",httpServletRequest.getRequestURI());
filterChain.doFilter(servletRequest,servletResponse);
}
log.info("耗時:{}ms",System.currentTimeMillis()-start);
}

@Override
publicvoiddestroy(){
log.info("destroyGZIPFilter");
}
}

/**
*@ClassName:FilterRegistration
*@Authorzhangjin
*@Date2022/3/260:36
*@Description:
*/
@Configuration
publicclassFilterRegistration{

@Resource
privateGZIPFiltergzipFilter;

@Bean
publicFilterRegistrationBeangzipFilterRegistrationBean(){
FilterRegistrationBeanregistration=newFilterRegistrationBean<>();
//Filter可以new,也可以使用依賴注入Bean
registration.setFilter(gzipFilter);
//過濾器名稱
registration.setName("gzipFilter");
//攔截路徑
registration.addUrlPatterns("/*");
//設(shè)置順序
registration.setOrder(1);
returnregistration;
}
}

實(shí)現(xiàn)RequestWrapper實(shí)現(xiàn)解壓和寫回Body的邏輯

/**
*@ClassName:UnZIPRequestWrapper
*@Authorzhangjin
*@Date2022/3/2611:02
*@Description:JsonString經(jīng)過壓縮后保存為二進(jìn)制文件->解壓縮后還原成JsonString轉(zhuǎn)換成byte[]寫回body中
*/
@Slf4j
publicclassUnZIPRequestWrapperextendsHttpServletRequestWrapper{

privatefinalbyte[]bytes;

publicUnZIPRequestWrapper(HttpServletRequestrequest)throwsIOException{
super(request);
try(BufferedInputStreambis=newBufferedInputStream(request.getInputStream());
ByteArrayOutputStreambaos=newByteArrayOutputStream()){
finalbyte[]body;
byte[]buffer=newbyte[1024];
intlen;
while((len=bis.read(buffer))>0){
baos.write(buffer,0,len);
}
body=baos.toByteArray();
if(body.length==0){
log.info("Body無內(nèi)容,無需解壓");
bytes=body;
return;
}
this.bytes=GZIPUtils.uncompressToByteArray(body);
}catch(IOExceptionex){
log.info("解壓縮步驟發(fā)生異常!");
ex.printStackTrace();
throwex;
}
}

@Override
publicServletInputStreamgetInputStream()throwsIOException{
finalByteArrayInputStreambyteArrayInputStream=newByteArrayInputStream(bytes);
returnnewServletInputStream(){

@Override
publicbooleanisFinished(){
returnfalse;
}

@Override
publicbooleanisReady(){
returnfalse;
}

@Override
publicvoidsetReadListener(ReadListenerreadListener){

}

publicintread()throwsIOException{
returnbyteArrayInputStream.read();
}
};
}

@Override
publicBufferedReadergetReader()throwsIOException{
returnnewBufferedReader(newInputStreamReader(this.getInputStream()));
}

}

附上壓縮工具類

publicclassGZIPUtils{

publicstaticfinalStringGZIP_ENCODE_UTF_8="UTF-8";

/**
*字符串壓縮為GZIP字節(jié)數(shù)組
*@paramstr
*@return
*/
publicstaticbyte[]compress(Stringstr){
returncompress(str,GZIP_ENCODE_UTF_8);
}

/**
*字符串壓縮為GZIP字節(jié)數(shù)組
*@paramstr
*@paramencoding
*@return
*/
publicstaticbyte[]compress(Stringstr,Stringencoding){
if(str==null||str.length()==0){
returnnull;
}
ByteArrayOutputStreamout=newByteArrayOutputStream();
GZIPOutputStreamgzip;
try{
gzip=newGZIPOutputStream(out);
gzip.write(str.getBytes(encoding));
gzip.close();
}catch(IOExceptione){
e.printStackTrace();
}
returnout.toByteArray();
}

/**
*GZIP解壓縮
*@parambytes
*@return
*/
publicstaticbyte[]uncompress(byte[]bytes){
if(bytes==null||bytes.length==0){
returnnull;
}
ByteArrayOutputStreamout=newByteArrayOutputStream();
ByteArrayInputStreamin=newByteArrayInputStream(bytes);
try{
GZIPInputStreamungzip=newGZIPInputStream(in);
byte[]buffer=newbyte[256];
intn;
while((n=ungzip.read(buffer))>=0){
out.write(buffer,0,n);
}
}catch(IOExceptione){
e.printStackTrace();
}
returnout.toByteArray();
}

/**
*解壓并返回String
*@parambytes
*@return
*/
publicstaticStringuncompressToString(byte[]bytes)throwsIOException{
returnuncompressToString(bytes,GZIP_ENCODE_UTF_8);
}

/**
*
*@parambytes
*@return
*/
publicstaticbyte[]uncompressToByteArray(byte[]bytes)throwsIOException{
returnuncompressToByteArray(bytes,GZIP_ENCODE_UTF_8);
}

/**
*解壓成字符串
*@parambytes壓縮后的字節(jié)數(shù)組
*@paramencoding編碼方式
*@return解壓后的字符串
*/
publicstaticStringuncompressToString(byte[]bytes,Stringencoding)throwsIOException{
byte[]result=uncompressToByteArray(bytes,encoding);
returnnewString(result);
}

/**
*解壓成字節(jié)數(shù)組
*@parambytes
*@paramencoding
*@return
*/
publicstaticbyte[]uncompressToByteArray(byte[]bytes,Stringencoding)throwsIOException{
if(bytes==null||bytes.length==0){
returnnull;
}
ByteArrayOutputStreamout=newByteArrayOutputStream();
ByteArrayInputStreamin=newByteArrayInputStream(bytes);
try{
GZIPInputStreamungzip=newGZIPInputStream(in);
byte[]buffer=newbyte[256];
intn;
while((n=ungzip.read(buffer))>=0){
out.write(buffer,0,n);
}
returnout.toByteArray();
}catch(IOExceptione){
e.printStackTrace();
thrownewIOException("解壓縮失敗!");
}
}

/**
*將字節(jié)流轉(zhuǎn)換成文件
*@paramfilename
*@paramdata
*@throwsException
*/
publicstaticvoidsaveFile(Stringfilename,byte[]data)throwsException{
if(data!=null){
Stringfilepath="/"+filename;
Filefile=newFile(filepath);
if(file.exists()){
file.delete();
}
FileOutputStreamfos=newFileOutputStream(file);
fos.write(data,0,data.length);
fos.flush();
fos.close();
System.out.println(file);
}
}

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實(shí)現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

  • 項目地址:https://github.com/YunaiV/yudao-cloud
  • 視頻教程:https://doc.iocoder.cn/video/

3. 測試效果

注意一個大坑:千萬不要直接將壓縮后的byte[]當(dāng)作字符串進(jìn)行傳輸,否則你會發(fā)現(xiàn)壓縮后的請求數(shù)據(jù)竟然比沒壓縮后的要大得多!一般有兩種傳輸壓縮后的byte[]的方式:

  • 將壓縮后的byet[]進(jìn)行base64編碼再傳輸字符串,這種方式會損失掉一部分GZIP的壓縮效果,適用于壓縮結(jié)果要存儲在Redis中的情況
  • 將壓縮后的byte[]以二進(jìn)制的形式寫入到文件中,請求時直接在body中帶上文件即可,用這種方式可以不損失壓縮效果

Postman測試Gzip壓縮數(shù)據(jù)請求:

  • 請求頭指定數(shù)據(jù)壓縮方式:
e66cba2a-711c-11ed-8abf-dac502259ad0.png
  • Body帶上壓縮后的byte[]寫入的二進(jìn)制文件
e67736f8-711c-11ed-8abf-dac502259ad0.png
  • 執(zhí)行請求,服務(wù)端正確處理了請求并且請求size縮小了將近一半,效果還是很不錯的,這樣GZIP壓縮數(shù)據(jù)的請求的處理就完成了,完整的項目代碼在下方
e69f980a-711c-11ed-8abf-dac502259ad0.png

4. Demo地址

  • https://gitee.com/wx_1bceb446a4/gziptest


審核編輯 :李倩


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • spring
    +關(guān)注

    關(guān)注

    0

    文章

    340

    瀏覽量

    14338
  • 傳輸數(shù)據(jù)
    +關(guān)注

    關(guān)注

    1

    文章

    122

    瀏覽量

    16101
  • 大數(shù)據(jù)
    +關(guān)注

    關(guān)注

    64

    文章

    8882

    瀏覽量

    137403

原文標(biāo)題:Spring Boot + Filter 實(shí)現(xiàn) Gzip 壓縮超大 json 對象,傳輸耗時大大減少

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    SSM開發(fā)環(huán)境的搭建教程 SSM與Spring Boot的區(qū)別

    SSM開發(fā)環(huán)境的搭建教程 SSM(Spring+SpringMVC+MyBatis)開發(fā)環(huán)境的搭建涉及多個步驟,以下是詳細(xì)的教程: 創(chuàng)建Maven項目 : 使用Maven工具創(chuàng)建一個新的Maven
    的頭像 發(fā)表于 12-16 18:13 ?365次閱讀

    Spring 應(yīng)用合并之路(二):峰回路轉(zhuǎn),柳暗花明

    提醒下,決定拋開 Spring Boot 內(nèi)置的父子容器方案,完全自己實(shí)現(xiàn)父子容器。 如何加載 web 項目? 現(xiàn)在的難題只有一個:如何加載 web 項目?加載完成后,如何持續(xù)持有 web 項目?經(jīng)過思考后,可以創(chuàng)建一個
    的頭像 發(fā)表于 12-12 11:22 ?693次閱讀

    Spring事務(wù)實(shí)現(xiàn)原理

    這些操作。 spring事務(wù)有編程式事務(wù)和聲明式事務(wù)兩種實(shí)現(xiàn)方式。編程式事務(wù)是通過編寫代碼來管理事務(wù)的提交、回滾、以及事務(wù)的邊界。這意味著開發(fā)者需要在代碼中顯式地調(diào)用事務(wù)的開始、提交和回滾。聲明式事務(wù)是通過配置來管理事務(wù),您可以使用注解或XML配置來
    的頭像 發(fā)表于 11-08 10:10 ?813次閱讀
    <b class='flag-5'>Spring</b>事務(wù)<b class='flag-5'>實(shí)現(xiàn)</b>原理

    如何使用gzip壓縮和解壓縮技術(shù)

    Nginx是一款高性能的Web服務(wù)器,它也能夠充當(dāng)反向代理服務(wù)器和負(fù)載均衡器。在Web應(yīng)用開發(fā)中,優(yōu)化網(wǎng)站速度是一個非常重要的工作。使用gzip壓縮和解壓縮技術(shù),可以有效減小傳輸文件的大小,提升網(wǎng)站的訪問速度。
    的頭像 發(fā)表于 09-29 15:57 ?385次閱讀

    JSON協(xié)議是什么,物聯(lián)網(wǎng)中的RTU中如何使用JSON協(xié)議和服務(wù)器交互

    一 概述 1.1 什么是 JSON JSON是JavaScript Object Notation的簡稱,中文含義為“JavaScript 對象表示法”,它是一種數(shù)據(jù)交換的文本格式,而不是一種編程
    的頭像 發(fā)表于 09-25 16:14 ?703次閱讀
    <b class='flag-5'>JSON</b>協(xié)議是什么,物聯(lián)網(wǎng)中的RTU中如何使用<b class='flag-5'>JSON</b>協(xié)議和服務(wù)器交互

    Spring Cloud Gateway網(wǎng)關(guān)框架

    SpringCloud Gateway功能特征如下: (1) 基于Spring Framework 5, Project Reactor 和 Spring Boot 2.0 進(jìn)行構(gòu)建; (2) 動態(tài)路由:能夠匹配任何請求屬性;
    的頭像 發(fā)表于 08-22 09:58 ?483次閱讀
    <b class='flag-5'>Spring</b> Cloud Gateway網(wǎng)關(guān)框架

    單片機(jī)boot0和boot1怎么設(shè)置

    單片機(jī)Boot0和Boot1簡介 Boot0和Boot1是單片機(jī)啟動模式選擇引腳,用于選擇單片機(jī)的啟動模式。 Boot0和
    的頭像 發(fā)表于 08-22 09:50 ?2396次閱讀

    vue+spring boot人員定位系統(tǒng)源碼,實(shí)現(xiàn)實(shí)時定位、智慧調(diào)度、軌跡追蹤

    、機(jī)具、物料上定位標(biāo)簽回傳的位置信息數(shù)據(jù),采用多維定位模式,精確定位人、機(jī)具、物料的實(shí)時位置,實(shí)現(xiàn)實(shí)時定位、物料標(biāo)簽配置、智慧調(diào)度、軌跡追蹤、工時統(tǒng)計、區(qū)域物料統(tǒng)計、電子圍欄等應(yīng)用功能。 技術(shù)架構(gòu):java+ spring boot
    的頭像 發(fā)表于 08-08 14:27 ?686次閱讀
    vue+<b class='flag-5'>spring</b> <b class='flag-5'>boot</b>人員定位系統(tǒng)源碼,<b class='flag-5'>實(shí)現(xiàn)</b>實(shí)時定位、智慧調(diào)度、軌跡追蹤

    玩轉(zhuǎn)Spring狀態(tài)機(jī)

    說起Spring狀態(tài)機(jī),大家很容易聯(lián)想到這個狀態(tài)機(jī)和設(shè)計模式中狀態(tài)模式的區(qū)別是啥呢?沒錯,Spring狀態(tài)機(jī)就是狀態(tài)模式的一種實(shí)現(xiàn),在介紹Spring狀態(tài)機(jī)之前,讓我們來看看設(shè)計模式中
    的頭像 發(fā)表于 06-25 14:21 ?934次閱讀
    玩轉(zhuǎn)<b class='flag-5'>Spring</b>狀態(tài)機(jī)

    UWB室內(nèi)外高精度一體化融合定位系統(tǒng)源碼 UWB技術(shù)定位系統(tǒng)應(yīng)用場景 Java+Spring boot+MYSQL?技術(shù)開發(fā)

    UWB室內(nèi)外高精度一體化融合定位系統(tǒng)源碼 UWB技術(shù)定位系統(tǒng)應(yīng)用場景 Java+Spring boot+MYSQL?技術(shù)開發(fā) 系統(tǒng)聚焦基于UWB(超寬帶)技術(shù)的底層定位網(wǎng)絡(luò)和定位算法,通過對定位分站
    的頭像 發(fā)表于 06-18 10:46 ?476次閱讀
    UWB室內(nèi)外高精度一體化融合定位系統(tǒng)源碼 UWB技術(shù)定位系統(tǒng)應(yīng)用場景 Java+<b class='flag-5'>Spring</b> <b class='flag-5'>boot</b>+MYSQL?技術(shù)開發(fā)

    ?PLC設(shè)備通過智能網(wǎng)關(guān)采用HTTP協(xié)議JSON文件對接MES、ERP等系統(tǒng)平臺

    ,字符可自由修改,舉例只是為了描述各種JSON文件的結(jié)構(gòu)實(shí)現(xiàn)。MQTT協(xié)議的發(fā)布/訂閱也是同樣的對應(yīng)方式。具體如下: 多個Key:Value的同級組合: 包含子對象: 增加時間戳,多種格式可以
    發(fā)表于 05-13 12:04

    Python壓縮和解壓縮實(shí)現(xiàn)代碼分享

    壓縮和解壓縮是日常常用的操作,不管是windows上圖形界面的操作,還是linux上用命令來進(jìn)行壓縮壓縮,總的而言都還是比較方便的。
    的頭像 發(fā)表于 04-11 11:28 ?1054次閱讀

    使用Spring Boot 3.2虛擬線程搭建靜態(tài)文件服務(wù)器

    Spring Boot 3.2 于 2023 年 11 月大張旗鼓地發(fā)布,標(biāo)志著 Java 開發(fā)領(lǐng)域的一個關(guān)鍵時刻。這一突破性的版本引入了一系列革命性的功能。
    的頭像 發(fā)表于 01-09 09:34 ?1120次閱讀
    使用<b class='flag-5'>Spring</b> <b class='flag-5'>Boot</b> 3.2虛擬線程搭建靜態(tài)文件服務(wù)器

    stm32中boot0和boot1怎么接

    BOOT0和BOOT1引腳通常是用作輸入引腳,并且默認(rèn)狀態(tài)下與地電位連接。當(dāng)需要更改啟動模式或使用引導(dǎo)加載程序時,可以通過控制這些引腳的狀態(tài)來實(shí)現(xiàn)。 引導(dǎo)模式有兩種:用戶模式和系統(tǒng)模式。用戶模式是指從主Flash或外部存儲器
    的頭像 發(fā)表于 12-27 10:22 ?1.8w次閱讀

    Spring狀態(tài)機(jī)的實(shí)現(xiàn)原理和使用方法

    說起 Spring 狀態(tài)機(jī),大家很容易聯(lián)想到這個狀態(tài)機(jī)和設(shè)計模式中狀態(tài)模式的區(qū)別是啥呢?沒錯,Spring 狀態(tài)機(jī)就是狀態(tài)模式的一種實(shí)現(xiàn),在介紹 Spring 狀態(tài)機(jī)之前,讓我們來看看
    的頭像 發(fā)表于 12-26 09:39 ?1977次閱讀
    <b class='flag-5'>Spring</b>狀態(tài)機(jī)的<b class='flag-5'>實(shí)現(xiàn)</b>原理和使用方法
    主站蜘蛛池模板: 体育生爆操| 97精品国产亚洲AV超碰| 快播h动漫网| 儿子操妈妈| 中文字幕高清在线观看| 神马午夜不卡片| 美女内射视频WWW网站午夜 | 国产三级影院| 扒开小处30p| 制服国产欧美亚洲日韩| 性色欲情网站IWWW| 人妖操女人| 毛片免费观看的视频| 国语大学生自产拍在线观看| a久久99精品久久久久久蜜芽| 亚洲精品久久区二区三区蜜桃臀| 少女free大陆| 13一18TV处流血TV| 拍戏被CAO翻了H| 国产精品免费久久久久影院| 少妇第一次交换| 国产精品爽黄69天堂A片| 热久久综合这里只有精品电影 | 国产成人精品一区二区三区视频| 亚洲欧美人成视频在线| 99久久免费精品国产免费| 扒开美女下面粉嫩粉嫩冒白浆| 国产精品久久久久久久久LI无码 | 日韩人妻少妇一区二区三区| 天上人间影院久久国产| 幺妹视频福利视频| 把腿张开再深点好爽宝贝动态图| 国产色情短视频在线网站| 巨污全肉np一女多男| 色老99九久精品偷偷鲁| 伊人久久国产精品| 东热rq大乱交| 玖玖爱精品视频| 开心成人社区| 美女久久久| 女生扒开下面|