精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

一種奇特的干掉 if..else 方式,Spring Boot+Aviator+Aop 挺有趣!

開發
從5.0.0版本開始,aviator升級成為了aviatorScript,成為一個高性能、輕量級寄宿于 JVM (包括 Android 平臺)之上的腳本語言。

aviator本來是一個輕量級、高性能的基于JVM的表達式引擎。不過從5.0.0版本開始,aviator升級成為了aviatorScript,成為一個高性能、輕量級寄宿于 JVM (包括 Android 平臺)之上的腳本語言。

根據官網的介紹,aviator支持的主要特性:

  • 支持數字、字符串、正則表達式、布爾值、正則表達式等基本類型,完整支持所有 Java 運算符及優先級等。
  • 函數是一等公民,支持閉包和函數式編程
  • 內置 bigint/decimal類型用于大整數和高精度運算,支持運算符重載得以讓這些類型使用普通的算術運算符 +-*/ 參與運算。
  • 完整的腳本語法支持,包括多行數據、條件語句、循環語句、詞法作用域和異常處理等。
  • 函數式編程結合 Sequence 抽象,便捷處理任何集合。
  • 輕量化的模塊系統。
  • 多種方式,方便地調用 Java 方法,完整支持 Java 腳本 API(方便從 Java 調用腳本)。
  • 豐富的定制選項,可作為安全的語言沙箱和全功能語言使用。
  • 輕量化,高性能,ASM 模式下通過直接將腳本翻譯成 JVM 字節碼,解釋模式可運行于 Android 等非標 Java 平臺。

使用場景包括:

  • 規則判斷及規則引擎
  • 公式計算
  • 動態腳本控制
  • 集合數據 ELT 等

一、Aviator的限制

  • 沒有if else、do while等語句,沒有賦值語句,僅支持邏輯表達式、算術表達式、三元表達式和正則匹配。
  • 不支持八進制數字字面量,僅支持十進制和十六進制數字字面量。

二、aviator基本使用

1. 基本表達式

要使用aviator,只需要添加相應依賴:

<dependency>
    <groupId>com.googlecode.aviator</groupId>
    <artifactId>aviator</artifactId>
    <version>5.3.3</version>
</dependency>

然后就可以進行表達式求值了:

// 返回值為16
Long r = (Long) AviatorEvaluator.execute("2 * (3 + 5)");

為了提升性能,往往先編譯表達式,然后可以反復執行,進行表達式求值:

Expression expression = AviatorEvaluator.compile("2 * (3 + 5)");
Long r = (Long) expression.execute();

aviator支持數字、字符串、布爾值等基本數據類型,數字類型值都當作long或double類型處理。

aviator表達式支持大部分的運算操作符,如常用的算術運算操作符(+、-、*、/、%)、邏輯運算操作符(&&、||、!)、比較運算操作符(>、>=、==、!=、<、<=)、位運算操作符(&、|、^、<<、>>)和優先級操作符,還支持三元操作表達(?:)、正則表達式(=~)。

一些例子:

// 返回 hello world
    String r = (String) AviatorEvaluator.execute("'hello' + ' world'");
    
    // 返回 true
    Boolean r = (Boolean) AviatorEvaluator.execute("100 > 80 && 30 < 40");
    
    // 三元表達式,返回 30
    Long r = (Long) AviatorEvaluator.execute("100 > 80 ? 30 : 40");
    
    // 正則表達式,正則表達式放在//之間,返回 true
    Boolean r = (Boolean) AviatorEvaluator.execute("'hello' =~ /[\\w]+/");

2. 表達式變量

跟其他表達式引擎一樣,aviator也是支持表達式求值時傳入參數的:

Long a = 12L;
Boolean r = (Boolean) AviatorEvaluator.exec("a > 10", a);

參數也可以是一個列表,如下:

List<Long> a = new ArrayList<>();
a.add(12L);
a.add(20L);
Boolean r = (Boolean) AviatorEvaluator.exec("a[0] > 10", a);

也可以是一個對象:

public static class Person {
        private String name;
        private Integer age;
    }

Person a = new Person("movee", 25);
Boolean r = (Boolean) AviatorEvaluator.exec("a.age > 10", a);

跟一般地,aviator會將參數放到一個map中:

Map<String, Object> env = new HashMap<>();
env.put("person", new Person("movee", 25));
env.put("a", 20L);
Object result = AviatorEvaluator.execute("person.name", env);

這樣一來,aviator可以非常方便的從json字符串中提取子json字符串:

String jsonStr = """
        {
            "a": {
                "b": [
                        {
                            "x": 3
                        },
                        {
                            "x": 4
                        }
                    ]
            }
        }
        """;


    JSONObject jsonObj = new JSONObject(jsonStr);
    // 結果返回 3
    Object value = AviatorEvaluator.execute("a.b[0]['x']", jsonObj.toMap());

3. 使用函數

aviator已經提供了很多開箱即用的函數了:

// 返回4
    Long r = (Long) AviatorEvaluator.execute("math.round(4.3)");
    
    // 返回5
    Long r = (Long) AviatorEvaluator.execute("string.length('hello')");
    
    // 返回一個ArrayList:[1,2,3]
    Object r = AviatorEvaluator.execute("seq.list(1,2,3)");

我們也可以自定義一個java函數,自己編寫一個類,繼承aviator的AbstractFunction類,然后實現相應的方法即可:

public class AddFunction extends AbstractFunction {

        /**
         * 函數實現的功能
         * @param env 參數
         * @param arg1 函數的第一個參數
         * @param arg2 函數的第二個參數
         * @return 返回值
         */
        @Override
        public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {
            long num1 = FunctionUtils.getNumberValue(arg1, env).longValue();
            long num2 = FunctionUtils.getNumberValue(arg2, env).longValue();
            return AviatorLong.valueOf(num1+num2);
        }

        /**
         * 注冊到aviator的名字
         * @return 函數名字
         */
        @Override
        public String getName() {
            return"add";
        }
    }

然后就可以注冊到aviator中,像使用內置函數一樣使用自定義函數:

// 注冊
    AviatorEvaluator.addFunction(new AddFunction());
    
    // 使用
    long sum = (Long) AviatorEvaluator.getInstance().execute("add(3,4)");

4. aviatorScript腳本

aviator已經升級為一個腳本語言,所以不僅僅能進行表達式求值,還可以執行腳本程序。

// 返回1
    Object r = AviatorEvaluator.execute("if (true) { return 1; } else { return 2; }");

aviatorScript腳本一般放到獨立的腳本文件中,文件名后綴一般為.av。

例如,我們編寫一個hello.av腳本文件,內容為:

if (a > 10) {
    return 10;
} else {
    return a;
}

然后就可以執行該腳本文件,并傳入參數a的值:

Map<String, Object> env = new HashMap<>();
    env.put("a", 30);
    Expression exp = AviatorEvaluator.getInstance().compileScript("./hello.av", true);
    Object result = exp.execute(env);

三、實操

利用aviator+aop實現參數校驗。

1. pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springboot-demo</artifactId>
        <groupId>com.et</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>Aviator</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!--AOP-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <!--Aviator-->
        <dependency>
            <groupId>com.googlecode.aviator</groupId>
            <artifactId>aviator</artifactId>
            <version>3.3.0</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.56</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.8.1</version>
        </dependency>

    </dependencies>
</project>

2. controller

在方法上加上aviator校驗規則:

package com.et.controller;

import com.et.annotation.Check;
import com.et.exception.HttpResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
publicclass HelloWorldController {
    @RequestMapping("/hello")
    public Map<String, Object> showHelloWorld(){
        Map<String, Object> map = new HashMap<>();
        map.put("msg", "HelloWorld");
        return map;
    }
    @GetMapping("/simple")
    @Check(ex = "name != null", msg = "Name cannot be empty")
    @Check(ex = "age != null", msg = "Age cannot be empty")
    @Check(ex = "age > 18", msg = "Age must be over 18 years old")
    @Check(ex = "phone != null", msg = "phone cannot be empty")
    @Check(ex = "phone =~ /^(1)[0-9]{10}$/", msg = "The phone number format is incorrect")
    @Check(ex = "string.startsWith(phone,\"1\")", msg = "The phone number must start with 1")
    @Check(ex = "idCard != null", msg = "ID number cannot be empty")
    @Check(ex = "idCard =~ /^[1-9]\\d{5}[1-9]\\d{3}((0[1-9])||(1[0-2]))((0[1-9])||(1\\d)||(2\\d)||(3[0-1]))\\d{3}([0-9]||X)$/", msg = "ID number format is incorrect")
    @Check(ex = "gender == 1", msg = "sex")
    @Check(ex = "date =~ /^[1-9][0-9]{3}-((0)[1-9]|(1)[0-2])-((0)[1-9]|[1,2][0-9]|(3)[0,1])$/", msg = "Wrong date format")
    @Check(ex = "date > '2019-12-20 00:00:00:00'", msg = "The date must be greater than 2019-12-20")
    public HttpResult simple(String name, Integer age, String phone, String idCard, String date) {
        System.out.println("name = " + name);
        System.out.println("age = " + age);
        System.out.println("phone = " + phone);
        System.out.println("idCard = " + idCard);
        System.out.println("date = " + date);
        return HttpResult.success();
    }
}

3. annotation

單個規則注解:

package com.et.annotation;

import java.lang.annotation.*;


@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
//add more on a method
@Repeatable(CheckContainer.class)
public @interface Check {

   String ex() default "";

   String msg() default "";

}

多個規則注解:

package com.et.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckContainer {

   Check[] value();
}

AOP攔截注解:

package com.et.annotation;

import com.et.exception.UserFriendlyException;
import com.googlecode.aviator.AviatorEvaluator;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;
import java.util.*;


@Aspect
@Configuration
publicclass AopConfig {

   /**
    * Aspects monitor multiple annotations, because one annotation is Check and multiple annotations are compiled to CheckContainer
    */
   @Pointcut("@annotation(com.et.annotation.CheckContainer) || @annotation(com.et.annotation.Check)")
   public void pointcut() {
   }

   @Before("pointcut()")
   public Object before(JoinPoint point) {
      //get params
      Object[] args = point.getArgs();
      //get param name
      Method method = ((MethodSignature) point.getSignature()).getMethod();
      LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
      String[] paramNames = u.getParameterNames(method);

      CheckContainer checkContainer = method.getDeclaredAnnotation(CheckContainer.class);
      List<Check> value = new ArrayList<>();

      if (checkContainer != null) {
         value.addAll(Arrays.asList(checkContainer.value()));
      } else {
         Check check = method.getDeclaredAnnotation(Check.class);
         value.add(check);
      }
      for (int i = 0; i < value.size(); i++) {
         Check check = value.get(i);
         String ex = check.ex();
         //In the rule engine, null is represented by nil
         ex = ex.replaceAll("null", "nil");
         String msg = check.msg();
         if (StringUtils.isEmpty(msg)) {
            msg = "server exception...";
         }

         Map<String, Object> map = new HashMap<>(16);
         for (int j = 0; j < paramNames.length; j++) {
            //Prevent index out of bounds
            if (j > args.length) {
               continue;
            }
            map.put(paramNames[j], args[j]);
         }
         Boolean result = (Boolean) AviatorEvaluator.execute(ex, map);
         if (!result) {
            thrownew UserFriendlyException(msg);
         }
      }
      returnnull;
   }
}

全局異常攔截:

package com.et.exception;

import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import javax.servlet.http.HttpServletRequest;


@Configuration
@ControllerAdvice
publicclass DefaultGlobalExceptionHandler extends ResponseEntityExceptionHandler {
   privatestaticfinal Logger LOGGER = LoggerFactory.getLogger(DefaultGlobalExceptionHandler.class);

   @Override
   protected ResponseEntity<Object> handleExceptionInternal(Exception ex, @Nullable Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {
      HttpResult httpResult = HttpResult.failure(status.is5xxServerError() ? ErrorCode.serverError.getDesc() : ErrorCode.paramError.getDesc());
      LOGGER.error("handleException, ex caught, contextPath={}, httpResult={}, ex.msg={}", request.getContextPath(), JSON.toJSONString(httpResult), ex.getMessage());
      returnsuper.handleExceptionInternal(ex, httpResult, headers, status, request);
   }

   @ExceptionHandler(Exception.class)
   protected ResponseEntity handleException(HttpServletRequest request, Exception ex) {
      boolean is5xxServerError;
      HttpStatus httpStatus;
      HttpResult httpResult;
      if (ex instanceof UserFriendlyException) {
         UserFriendlyException userFriendlyException = (UserFriendlyException) ex;
         is5xxServerError = userFriendlyException.getHttpStatusCode() >= 500;
         httpStatus = HttpStatus.valueOf(userFriendlyException.getHttpStatusCode());
         httpResult = HttpResult.failure(userFriendlyException.getErrorCode(), userFriendlyException.getMessage());
      } elseif (ex instanceof IllegalArgumentException) {
         // Spring assertions are used in parameter judgment. requireTrue will throw an IllegalArgumentException. The client cannot handle 5xx exceptions, so 200 is still returned.
         httpStatus = HttpStatus.OK;
         is5xxServerError = false;
         httpResult = HttpResult.failure("Parameter verification error or data abnormality!");
      } else {
         httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;
         is5xxServerError = true;
         httpResult = HttpResult.failure(ErrorCode.serverError.getDesc());
      }
      if (is5xxServerError) {
         LOGGER.error("handleException, ex caught, uri={}, httpResult={}", request.getRequestURI(), JSON.toJSONString(httpResult), ex);
      } else {
         LOGGER.error("handleException, ex caught, uri={}, httpResult={}, ex.msg={}", request.getRequestURI(), JSON.toJSONString(httpResult), ex.getMessage());
      }
      returnnew ResponseEntity<>(httpResult, httpStatus);
   }

}

責任編輯:趙寧寧 來源: 程序員小富
相關推薦

2025-03-12 14:09:56

2024-04-01 08:38:57

Spring@AspectAOP

2019-04-25 14:25:24

Spring Bootif elseJava

2025-06-26 01:10:00

服務定位解析器Spring

2022-08-18 09:38:02

Spring跨域

2021-06-11 00:11:23

GPS數據協議

2013-05-22 15:31:07

AOP的CGlib實現

2014-12-01 09:54:40

JavaScript

2024-04-26 08:58:54

if-else代碼JavaSpring

2022-02-17 13:39:09

AOP接口方式

2020-11-09 14:03:51

Spring BootMaven遷移

2023-07-27 08:14:29

2025-07-08 08:20:39

2021-04-20 08:02:08

業務數據用戶

2023-01-26 23:46:15

2015-05-06 10:05:22

javajava框架spring aop

2022-06-06 15:44:24

大數據數據分析思維模式

2025-06-26 01:22:00

SpringBean開發

2021-11-26 11:07:14

cowsay命令Linux

2024-01-12 16:20:04

點贊
收藏

51CTO技術棧公眾號

亚洲福利在线观看视频| 在线看片中文字幕| 色在线视频观看| 欧美经典一区二区| 91视频免费进入| 1级黄色大片儿| 成人看的视频| 精品美女一区二区| 精品www久久久久奶水| 成人免费网站在线观看视频| 91在线精品一区二区| 国产美女久久久| 天海翼一区二区| 日韩精品永久网址| 亚洲精品大尺度| 成年人网站av| 欧美va在线观看| 亚洲18色成人| 三上悠亚免费在线观看| 麻豆影视在线| av色综合久久天堂av综合| 国产视频999| 男人天堂av在线播放| 欧美久久视频| 久久久成人精品| 亚洲国产av一区| 97久久综合区小说区图片区| 欧美日韩一二三| 精品中文字幕av| 美女精品导航| 亚洲男同性视频| 亚洲日本精品一区| 国产福利在线观看| 91啪亚洲精品| 国产专区一区二区| 亚洲xxxx天美| 国产福利91精品一区| 91精品久久久久久久久久入口| 成年人免费高清视频| 国产在线欧美| 九九热视频这里只有精品| 五月婷婷婷婷婷| 欧美日韩在线播放视频| 亚洲品质视频自拍网| 亚洲香蕉中文网| 中文字幕久久精品一区二区| 日韩一区二区三区精品视频| 51自拍视频在线观看| 视频欧美精品| 91精品国产一区二区三区蜜臀| 人人干人人干人人| 国产精品久久久久久久久久齐齐| 在线影院国内精品| 日本熟妇人妻中出| 欧美日韩电影免费看| 日本乱人伦aⅴ精品| 日韩欧美精品在线观看视频| 亚洲国产福利| 欧美亚洲自拍偷拍| 日日噜噜噜噜久久久精品毛片| 亚洲成人av观看| 欧美色图第一页| 性生生活大片免费看视频| 日韩美香港a一级毛片| 91精品中文字幕一区二区三区| 亚洲免费成人在线视频| 国产区一区二| 亚洲高清av在线| 成人影视免费观看| 欧美日韩水蜜桃| www国产精品com| 免费人成年激情视频在线观看| 亚洲午夜在线| 欧美亚洲国产另类| 成人毛片一区二区三区| 美女视频黄a大片欧美| 成人激情免费在线| 国产成人自拍一区| 2017欧美狠狠色| 涩涩涩999| av软件在线观看| 天天综合色天天| 99热手机在线| 麻豆视频久久| 精品伊人久久97| 久操视频在线观看免费| 永久亚洲成a人片777777| 久久久久亚洲精品| 亚洲精品国产无码| 国产精品亚洲一区二区三区在线 | 91欧美一区二区| 色就是色欧美| 国内在线视频| 在线观看成人免费视频| 久久国产免费视频| 精品国产99| 九九热这里只有在线精品视| 欧美精品一二三四区| 国内精品视频666| 久久精品美女| 50度灰在线| 色噜噜狠狠色综合中国| 日本黄色一级网站| 你懂的一区二区三区| 欧美成人在线网站| 香蕉污视频在线观看| 成人激情校园春色| 亚洲一区二区四区| 伊人久久国产| 日韩精品一区二区三区老鸭窝| 国产交换配乱淫视频免费| 综合激情在线| 国产精品偷伦视频免费观看国产| 神马午夜精品95| 亚洲视频一区二区在线观看| 91淫黄看大片| 老牛影视av一区二区在线观看| 久久精品福利视频| 中文字幕av第一页| 91尤物视频在线观看| 免费的av在线| 国产精品亲子伦av一区二区三区| 日韩精品极品在线观看播放免费视频| 欧美日韩精品在线观看视频| 美女国产一区二区三区| 女同一区二区| 涩涩av在线| 亚洲国产高清自拍| 免费中文字幕在线观看| 激情综合网av| 一区二区免费在线观看| 日韩欧美一区二区三区在线观看 | 亚洲日本视频| 97影院在线午夜| a视频在线播放| 欧美丰满少妇xxxxx高潮对白 | 国产区精品区| 欧美洲成人男女午夜视频| 亚洲精品中文字幕成人片| 亚洲三级免费观看| 日本黄色的视频| 99成人超碰| 91久久精品久久国产性色也91| 99青草视频在线播放视| 在线视频一区二区三| 欧美日韩高清丝袜| 日韩av一区二区三区| 久久久久久久久久久一区| 激情黄产视频在线免费观看| 亚洲国产精品久久| 日韩精品1区2区| 久久综合五月天婷婷伊人| 国产成人无码精品久久久性色| 国产主播性色av福利精品一区| 久久久亚洲精品视频| 日本美女一级片| 午夜精品久久久久影视| 亚洲欧美视频在线播放| 久久久精品网| 日韩欧美亚洲在线| 激情小说亚洲| 久热99视频在线观看| 亚洲女同志亚洲女同女播放| 亚洲午夜av在线| 精品影片一区二区入口| 美女久久一区| 影音欧美亚洲| 97久久亚洲| 欧美综合国产精品久久丁香| 第三区美女视频在线| 欧美高清激情brazzers| 黄色小视频在线免费看| 久久亚洲私人国产精品va媚药| 国产精品69页| 99久久精品网站| 国产精品三区在线| 亚洲午夜天堂| 日韩亚洲在线观看| 免费看黄色一级视频| 一本一道久久a久久精品| 国产主播av在线| 国产高清在线观看免费不卡| 2022亚洲天堂| 99九九热只有国产精品| 国产精品theporn88| 日韩av中字| 欧美伦理91i| 你懂的视频在线免费| 欧美一区二区三区视频| 日韩男人的天堂| 国产精品网曝门| 黄色av电影网站| 蜜臂av日日欢夜夜爽一区| 国产 欧美 日韩 一区| 国产探花在线精品一区二区| 114国产精品久久免费观看| 三上悠亚一区二区| 欧美激情中文网| 91电影在线播放| 亚洲国产天堂网精品网站| 一级特黄aaa大片在线观看| 亚洲va中文字幕| 一区二区三区影视| 2014亚洲片线观看视频免费| 少妇献身老头系列| 奇米精品一区二区三区在线观看一 | 亚洲女人的天堂| 无码一区二区三区在线| 国产91精品一区二区麻豆网站| 手机看片福利日韩| 亚洲毛片网站| 精品日韩在线播放| av在线不卡顿| 国产伦精品一区二区三区| 国产精品视频一区二区三区综合| 国产精品第七影院| 欧美激情护士| 久久久久久一区二区三区| 91大神在线网站| 亚洲性av网站| 无码精品人妻一区二区| 精品国产乱码久久久久久蜜臀| 国产孕妇孕交大片孕| 日本丶国产丶欧美色综合| 日本熟妇一区二区| 亚洲综合成人在线视频| 手机在线免费看片| 中文一区在线播放| 欧美波霸videosex极品| 久久久久国产精品麻豆| 国产精品福利导航| 成人午夜看片网址| av在线天堂网| 国产成人啪午夜精品网站男同| 天堂中文av在线| 奇米色777欧美一区二区| 成人小视频在线观看| 97在线免费视频观看| 久久久久久美女精品| 亚洲福利av在线| 欧美日韩中文一区二区| 日本在线一区| 欧美精品一区二区久久| 日本一区二区精品视频| 伊人久久大香线蕉无限次| 久久偷看各类wc女厕嘘嘘偷窃 | 99久久精品久久亚洲精品| 日本一区二区高清| 中文字幕第69页| 色哟哟网站入口亚洲精品| 亚洲欧美精品久久| 国产精品久线观看视频| 老司机福利在线观看| 国产精品―色哟哟| 黄色精品视频在线观看| 成人欧美一区二区三区视频网页| 国产在线免费看| 亚洲精品中文在线| 国产精品成人久久| 五月综合激情网| 三级视频在线观看| 欧美亚洲图片小说| 国产孕妇孕交大片孕| 日韩欧美一二三| 天堂中文在线看| 亚洲精品在线不卡| av电影在线观看| 美女av一区二区| 激情图片在线观看高清国产| 91大神福利视频在线| 久久99久久99精品免观看软件| 国产九九精品视频| 亚洲天堂av资源在线观看| 九九久久99| 久久国产成人午夜av影院宅| 欧美xxxx吸乳| 亚洲综合国产| 国产精品视频中文字幕| 国产aⅴ综合色| 人人妻人人藻人人爽欧美一区| 国产精品国产三级国产普通话三级| 青青草偷拍视频| 欧美日韩亚洲激情| 97caocao| 日韩黄色高清视频| 秋霞影院午夜丰满少妇在线视频| 久久久久久久国产精品视频| 欧美成人影院| 2019国产精品视频| 亚洲人成网www| 日本黄xxxxxxxxx100| 国产精品久久久久久久久久妞妞 | 成人午夜在线影视| 欧美激情网站在线观看| 成人性教育av免费网址| 亚洲aⅴ男人的天堂在线观看| 日韩精品社区| 精品一区二区成人免费视频| 国产精品主播| 午夜诱惑痒痒网| 久久久久国产一区二区三区四区| a级黄色片免费看| 色av综合在线| 亚洲精品视频专区| 日韩亚洲综合在线| 国产日韩电影| 国产精品三区在线| 天天做综合网| 日本成人在线免费视频| 不卡av在线免费观看| 日韩免费av一区| 一本在线高清不卡dvd| 午夜精品在线播放| 日韩亚洲精品电影| 成人日韩在线| 国产精品日韩一区二区| 国产精品99一区二区三区| 国产成人在线免费看| 福利视频网站一区二区三区| 四虎影视1304t| 欧美性猛交xxxx乱大交退制版| 天堂中文字幕av| 欧美黑人巨大xxx极品| 久久精品黄色| 日韩偷拍一区二区| 性色av一区二区怡红| 尤物网站在线观看| 亚洲一区二区三区精品在线| 国产成人精品一区二区无码呦| 最近2019年好看中文字幕视频 | 国模 一区 二区 三区| 九九九九九伊人| 国产精品国产精品国产专区不蜜| 亚洲熟妇无码乱子av电影| 亚洲精品国产精品国自产在线| 成人国产电影在线观看| 国产精品久久亚洲7777| 黄色亚洲精品| 国产精品成人免费一区久久羞羞| 一区二区三区欧美激情| 97人妻人人澡人人爽人人精品| 色哟哟入口国产精品| 久草综合在线| 亚洲综合视频一区| 久久99热99| 少妇影院在线观看| 日韩一区二区免费视频| 污视频网站在线免费| 国产精品麻豆免费版| 亚洲精品日本| 免费中文字幕av| 色婷婷综合在线| 成人激情电影在线看| 国产日韩在线看| 欧美a级片一区| 久久久久亚洲av无码网站| 樱桃国产成人精品视频| 国产精品小说在线| 日韩最新在线| 日本成人在线免费视频| 中文字幕乱码亚洲精品一区| 一级片一区二区三区| 欧美成人合集magnet| 亚洲日本va中文字幕| 日韩xxxx视频| 久久久久久久久久久久久久久99| 亚洲免费视频二区| 久久色在线播放| 97青娱国产盛宴精品视频| 凹凸国产熟女精品视频| 91亚洲永久精品| 中文字幕一区二区三区四区视频 | 91九色视频在线观看| 精品999成人| 91激情视频在线观看| 欧美精选在线播放| 成人影音在线| 日韩欧美国产二区| 国产呦萝稀缺另类资源| 国产成人无码一区二区三区在线| 亚洲欧美日韩第一区| 亚洲一区二区三区久久久| 国产乱子伦精品无码专区| 久久久久99精品国产片| 国产精品视频久久久久久| 久久久久亚洲精品| 欧美在线色图| 欧美久久久久久久久久久| 日本精品一级二级| 四虎影院观看视频在线观看| 欧美激情专区| 国产成人免费在线视频| 无码人妻一区二区三区线| 欧美成人高清视频| 精品国产一区探花在线观看| 久久艹这里只有精品| 在线观看av一区二区| 国产精品蜜臀| 中文有码久久| 久久久久久麻豆|