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

使用 Mapstructure 解析 Json,你學會了嗎?

開發 前端
內部使用了大量的反射,這可能會對一些特殊場景帶來性能隱患。所以大家在使用的時候,一定要充分考慮產品邏輯以及場景。

背景

前幾天群里的小伙伴問了一個這樣的問題:

圖片圖片

其實質就是在面對 value 類型不確定的情況下,怎么解析這個 json?

我下意識就想到了 [mapstructure](https://github.com/mitchellh/mapstructure) 這個庫,它可以幫助我們類似 PHP 那樣去處理弱類型的結構。

介紹

先來介紹一下 mapstructure 這個庫主要用來做什么的吧,官網是這么介紹的:

mapstructure 是一個 Go 庫,用于將通用映射值解碼為結構,反之亦然,同時提供有用的錯誤處理。

該庫在解碼數據流(JSON、Gob 等)中的值時最為有用,因為在讀取部分數據之前,您并不十分清楚底層數據的結構。因此,您可以讀取 map[string]interface{} 并使用此庫將其解碼為適當的本地 Go 底層結構。

簡單來說,它擅長解析一些我們并不十分清楚底層數據結構的數據流到我們定義的結構體中。

下面我們通過幾個例子來簡單介紹一下 mapstructure 怎么使用。

例子

普通形式

func normalDecode() {
 type Person struct {
  Name   string
  Age    int
  Emails []string
  Extra  map[string]string
 }

 // 此輸入可以來自任何地方,但通常來自諸如解碼 JSON 之類的東西,我們最初不太確定結構。
 input := map[string]interface{}{
  "name":   "Tim",
  "age":    31,
  "emails": []string{"one@gmail.com", "two@gmail.com", "three@gmail.com"},
  "extra": map[string]string{
   "twitter": "Tim",
  },
 }

 var result Person
 err := mapstructure.Decode(input, &result)
 if err != nil {
  panic(err)
 }

 fmt.Printf("%#v\n", result)
}

輸出:

main.Person{Name:"Tim", Age:31, Emails:[]string{"one@gmail.com", "two@gmail.com", "three@gmail.com"}, Extra:map[string]string{"twitter":"Tim"}}

這個方式應該是我們最經常使用的,非常簡單的將 map[string]interface{} 映射到我們的結構體中。

在這里,我們并沒有指定每個 field 的 tag,讓 mapstructure 自動去映射。

如果我們的 input 是一個 json 字符串,那么我們需要將 json 字符串解析為 map[string]interface{} 之后,再將其映射到我們的結構體中。

func jsonDecode() {
 var jsonStr = `{
 "name": "Tim",
 "age": 31,
 "gender": "male"
}`

 type Person struct {
  Name   string
  Age    int
  Gender string
 }
 m := make(map[string]interface{})
 err := json.Unmarshal([]byte(jsonStr), &m)
 if err != nil {
  panic(err)
 }

 var result Person
 err = mapstructure.Decode(m, &result)
 if err != nil {
  panic(err.Error())
 }
 fmt.Printf("%#v\n", result)
}

輸出:

main.Person{Name:"Tim", Age:31, Gender:"male"}

嵌入式結構

mapstructure 允許我們壓縮多個嵌入式結構,并通過 squash 標簽進行處理。

func embeddedStructDecode() {
 // 使用 squash 標簽允許壓縮多個嵌入式結構。通過創建多種類型的復合結構并對其進行解碼來演示此功能。
 type Family struct {
  LastName string
 }
 type Location struct {
  City string
 }
 type Person struct {
  Family    `mapstructure:",squash"`
  Location  `mapstructure:",squash"`
  FirstName string
 }

 input := map[string]interface{}{
  "FirstName": "Tim",
  "LastName":  "Liu",
  "City":      "China, Guangdong",
 }

 var result Person
 err := mapstructure.Decode(input, &result)
 if err != nil {
  panic(err)
 }

 fmt.Printf("%s %s, %s\n", result.FirstName, result.LastName, result.City)
}

輸出:

Tim Liu, China, Guangdong

在這個例子中, Person 里面有著 Location 和 Family 的嵌入式結構體,通過 squash 標簽進行壓縮,從而達到平鋪的作用。

元數據

func metadataDecode() {
 type Person struct {
  Name   string
  Age    int
  Gender string
 }

 // 此輸入可以來自任何地方,但通常來自諸如解碼 JSON 之類的東西,我們最初不太確定結構。
 input := map[string]interface{}{
  "name":  "Tim",
  "age":   31,
  "email": "one@gmail.com",
 }

 // 對于元數據,我們制作了一個更高級的 DecoderConfig,以便我們可以更細致地配置所使用的解碼器。在這種情況下,我們只是告訴解碼器我們想要跟蹤元數據。
 var md mapstructure.Metadata
 var result Person
 config := &mapstructure.DecoderConfig{
  Metadata: &md,
  Result:   &result,
 }

 decoder, err := mapstructure.NewDecoder(config)
 if err != nil {
  panic(err)
 }

 if err = decoder.Decode(input); err != nil {
  panic(err)
 }

 fmt.Printf("value: %#v, keys: %#v, Unused keys: %#v, Unset keys: %#v\n", result, md.Keys, md.Unused, md.Unset)
}

輸出:

value: main.Person{Name:"Tim", Age:31, Gender:""}, keys: []string{"Name", "Age"}, Unused keys: []string{"email"}, Unset keys: []string{"Gender"}

從這個例子我們可以看出,使用 Metadata 可以記錄我們結構體以及 map[string]interface{} 的差異,相同的部分會正確映射到對應的字段中,而差異則使用了 Unused 和 Unset 來表達。

  • Unused:map 中有著結構體所沒有的字段。
  • Unset:結構體中有著 map 中所沒有的字段。

避免空值的映射

這里的使用其實和內置的 json 庫使用方式是一樣的,都是借助 omitempty 標簽來解決。

func omitemptyDecode() {
 // 添加 omitempty 注釋以避免空值的映射鍵
 type Family struct {
  LastName string
 }
 type Location struct {
  City string
 }
 type Person struct {
  *Family   `mapstructure:",omitempty"`
  *Location `mapstructure:",omitempty"`
  Age       int
  FirstName string
 }

 result := &map[string]interface{}{}
 input := Person{FirstName: "Somebody"}
 err := mapstructure.Decode(input, &result)
 if err != nil {
  panic(err)
 }

 fmt.Printf("%+v\n", result)
}

輸出:

&map[Age:0 FirstName:Somebody]

這里我們可以看到 *Family 和 *Location 都被設置了 omitempty,所以在解析過程中會忽略掉空值。而 Age 沒有設置,并且 input 中沒有對應的 value,所以在解析中使用對應類型的零值來表達,而 int 類型的零值就是 0。

剩余字段

func remainDataDecode() {
 type Person struct {
  Name  string
  Age   int
  Other map[string]interface{} `mapstructure:",remain"`
 }

 input := map[string]interface{}{
  "name":   "Tim",
  "age":    31,
  "email":  "one@gmail.com",
  "gender": "male",
 }

 var result Person
 err := mapstructure.Decode(input, &result)
 if err != nil {
  panic(err)
 }

 fmt.Printf("%#v\n", result)
}

輸出:

main.Person{Name:"Tim", Age:31, Other:map[string]interface {}{"email":"one@gmail.com", "gender":"male"}}

從代碼可以看到 Other 字段被設置了 remain,這意味著 input 中沒有正確映射的字段都會被放到 Other 中,從輸出可以看到,email 和 gender 已經被正確的放到 Other 中了。

自定義標簽

func tagDecode() {
 // 請注意,結構類型中定義的 mapstructure 標簽可以指示將值映射到哪些字段。
 type Person struct {
  Name string `mapstructure:"person_name"`
  Age  int    `mapstructure:"person_age"`
 }

 input := map[string]interface{}{
  "person_name": "Tim",
  "person_age":  31,
 }

 var result Person
 err := mapstructure.Decode(input, &result)
 if err != nil {
  panic(err)
 }

 fmt.Printf("%#v\n", result)
}

輸出:

main.Person{Name:"Tim", Age:31}

在 Person 結構中,我們將 person_name 和 person_age 分別映射到 Name 和 Age 中,從而達到在不破壞結構的基礎上,去正確的解析。

弱類型解析

正如前面所說,mapstructure 提供了類似 PHP 解析弱類型結構的方法。

func weaklyTypedInputDecode() {
 type Person struct {
  Name   string
  Age    int
  Emails []string
 }

 // 此輸入可以來自任何地方,但通常來自諸如解碼 JSON 之類的東西,由 PHP 等弱類型語言生成。
 input := map[string]interface{}{
  "name":   123,  // number => string
  "age":    "31", // string => number
  "emails": map[string]interface{}{}, // empty map => empty array
 }

 var result Person
 config := &mapstructure.DecoderConfig{
  WeaklyTypedInput: true,
  Result:           &result,
 }

 decoder, err := mapstructure.NewDecoder(config)
 if err != nil {
  panic(err)
 }

 err = decoder.Decode(input)
 if err != nil {
  panic(err)
 }

 fmt.Printf("%#v\n", result)
}

輸出:

main.Person{Name:"123", Age:31, Emails:[]string{}}

從代碼可以看到,input 中的 name、age 和 Person 結構體中的 Name、Age 類型不一致,而 email 更是離譜,一個字符串數組,一個是 map。

但是我們通過自定義 DecoderConfig,將 WeaklyTypedInput 設置成 true 之后,mapstructure 很容易幫助我們解決這類弱類型的解析問題。

但是也不是所有問題都能解決,通過源碼我們可以知道有如下限制:

//   - bools to string (true = "1", false = "0")
//   - numbers to string (base 10)
//   - bools to int/uint (true = 1, false = 0)
//   - strings to int/uint (base implied by prefix)
//   - int to bool (true if value != 0)
//   - string to bool (accepts: 1, t, T, TRUE, true, True, 0, f, F,
//     FALSE, false, False. Anything else is an error)
//   - empty array = empty map and vice versa
//   - negative numbers to overflowed uint values (base 10)
//   - slice of maps to a merged map
//   - single values are converted to slices if required. Each
//     element is weakly decoded. For example: "4" can become []int{4}
//     if the target type is an int slice.

大家使用這種弱類型解析的時候也需要注意。

錯誤處理

mapstructure 錯誤提示非常的友好,下面我們來看看遇到錯誤時,它是怎么提示的。

func decodeErrorHandle() {
 type Person struct {
  Name   string
  Age    int
  Emails []string
  Extra  map[string]string
 }

 input := map[string]interface{}{
  "name":   123,
  "age":    "bad value",
  "emails": []int{1, 2, 3},
 }

 var result Person
 err := mapstructure.Decode(input, &result)
 if err != nil {
  fmt.Println(err.Error())
 }
}

輸出:

5 error(s) decoding:

* 'Age' expected type 'int', got unconvertible type 'string', value: 'bad value'
* 'Emails[0]' expected type 'string', got unconvertible type 'int', value: '1'
* 'Emails[1]' expected type 'string', got unconvertible type 'int', value: '2'
* 'Emails[2]' expected type 'string', got unconvertible type 'int', value: '3'
* 'Name' expected type 'string', got unconvertible type 'int', value: '123'

這里的錯誤提示會告訴我們每個字段,字段里的值應該需要怎么表達,我們可以通過這些錯誤提示,比較快的去修復問題。

總結

從上面這些例子看看到 mapstructure 的強大之處,很好的幫我們解決了實實在在的問題,也在節省我們的開發成本。

但是從源碼來看,內部使用了大量的反射,這可能會對一些特殊場景帶來性能隱患。所以大家在使用的時候,一定要充分考慮產品邏輯以及場景。

以下貼一小段刪減過的源碼:

// Decode decodes the given raw interface to the target pointer specified
// by the configuration.
func (d *Decoder) Decode(input interface{}) error {
 return d.decode("", input, reflect.ValueOf(d.config.Result).Elem())
}

// Decodes an unknown data type into a specific reflection value.
func (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) error {
 ....

 var err error
 outputKind := getKind(outVal)
 addMetaKey := true
 switch outputKind {
 case reflect.Bool:
  err = d.decodeBool(name, input, outVal)
 case reflect.Interface:
  err = d.decodeBasic(name, input, outVal)
 case reflect.String:
  err = d.decodeString(name, input, outVal)
 case reflect.Int:
  err = d.decodeInt(name, input, outVal)
 case reflect.Uint:
  err = d.decodeUint(name, input, outVal)
 case reflect.Float32:
  err = d.decodeFloat(name, input, outVal)
 case reflect.Struct:
  err = d.decodeStruct(name, input, outVal)
 case reflect.Map:
  err = d.decodeMap(name, input, outVal)
 case reflect.Ptr:
  addMetaKey, err = d.decodePtr(name, input, outVal)
 case reflect.Slice:
  err = d.decodeSlice(name, input, outVal)
 case reflect.Array:
  err = d.decodeArray(name, input, outVal)
 case reflect.Func:
  err = d.decodeFunc(name, input, outVal)
 default:
  // If we reached this point then we weren't able to decode it
  return fmt.Errorf("%s: unsupported type: %s", name, outputKind)
 }

 // If we reached here, then we successfully decoded SOMETHING, so
 // mark the key as used if we're tracking metainput.
 if addMetaKey && d.config.Metadata != nil && name != "" {
  d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
 }

 return err
}


責任編輯:武曉燕 來源: 愛發白日夢的后端
相關推薦

2023-06-26 13:08:52

GraphQL服務數據

2024-10-11 09:15:33

2024-02-02 11:03:11

React數據Ref

2025-01-02 10:02:44

2024-02-05 13:52:30

?Thread對象強引用

2023-10-30 07:05:31

2024-01-19 08:25:38

死鎖Java通信

2023-01-10 08:43:15

定義DDD架構

2024-02-04 00:00:00

Effect數據組件

2023-07-26 13:11:21

ChatGPT平臺工具

2024-09-06 07:29:05

2022-12-22 08:14:54

2022-11-08 08:45:30

Prettier代碼格式化工具

2024-01-02 12:05:26

Java并發編程

2023-08-01 12:51:18

WebGPT機器學習模型

2024-05-22 08:03:15

2024-08-19 10:24:14

2025-01-14 08:32:55

JWT令牌.NET

2024-02-27 08:39:19

RustJSON字符串

2023-01-30 09:01:54

圖表指南圖形化
點贊
收藏

51CTO技術棧公眾號

久久精品91久久久久久再现| 狠狠色狠狠色综合日日小说| 91精品中国老女人| 中文字幕手机在线观看| 99精品在免费线中文字幕网站一区 | 97精品视频在线| 手机看片福利视频| 精品视频一区二区三区在线观看 | 在线观看日本网站| 99精品综合| 精品不卡在线视频| 日本精品免费在线观看| 麻豆av免费在线观看| 高清视频一区二区| 欧美在线观看视频| 蜜桃av.com| 日韩激情毛片| 91精品国产综合久久久久久| 干日本少妇首页| 性网站在线观看| 久久亚洲精华国产精华液| 亚洲xxxxx电影| 五月婷婷六月婷婷| 亚洲日本免费| 蜜臀久久99精品久久久无需会员| 青青草成人免费视频| 在线视频成人| 欧洲av一区二区嗯嗯嗯啊| 17c丨国产丨精品视频| 91激情在线| 久久午夜电影网| 成人自拍爱视频| 国产又粗又猛又黄又爽| 日日夜夜免费精品| 欧美一区二区三区……| 久久99久久98精品免观看软件 | 国产成人免费av一区二区午夜| 日韩欧美精品中文字幕| 婷婷五月综合缴情在线视频| 伊人春色在线观看| 成人欧美一区二区三区黑人麻豆| 日韩欧美一区二区三区四区| 欧美色综合一区二区三区| 成人动漫中文字幕| 99久久精品免费看国产一区二区三区| 在线观看视频二区| 日韩影院免费视频| 欧美一级在线亚洲天堂| 国产成人无码精品亚洲| 精品二区久久| 久久亚洲欧美日韩精品专区 | 91久久嫩草影院一区二区| 波多野结衣电车痴汉| 美女国产一区| 91超碰caoporn97人人| 日韩成人在线免费视频| 怡红院精品视频在线观看极品| 美女黄色丝袜一区| 国产在线一卡二卡| 午夜欧美精品久久久久久久| 色综合天天狠天天透天天伊人| 麻豆精品一区二区三区视频| 欧美黄色一区二区| 欧美激情三级免费| 日韩经典在线观看| 久久国产高清| 国产精品国产福利国产秒拍| 岳乳丰满一区二区三区| 麻豆免费精品视频| 91九色视频在线观看| 丰满熟妇人妻中文字幕| 99国内精品久久| 欧美日韩一区在线观看视频| 国产69精品久久app免费版| 中日韩免费视频中文字幕| 中文字幕一区二区三区四区五区人 | 国产亚洲欧洲997久久综合| 亚洲欧美综合一区| 色呦呦在线观看视频| 精品久久久久久久中文字幕| 婷婷丁香激情网| 国产精品1区在线| 精品成人私密视频| 中文字幕黄色网址| 欧美成人国产| 91精品国产91久久久| 凹凸精品一区二区三区| 国产精品18久久久久久久久| 亚洲欧美一区二区三区久久| 欧美色图亚洲激情| 久久一本综合| 久久久视频精品| 波多野结衣视频网址| 国产精品中文字幕一区二区三区| 国产日韩亚洲精品| yjizz视频网站在线播放| 亚洲欧美日韩国产成人精品影院| 国产成人无码a区在线观看视频| 国产成人精品123区免费视频| 91 com成人网| 极品白嫩丰满美女无套| 香蕉综合视频| 欧美自拍视频在线观看| 99国产精品一区二区三区| 久久青草国产手机看片福利盒子 | 欧美日韩国产小视频| 婷婷五月精品中文字幕| 欧美黄色大片在线观看| 91a在线视频| 精品国产区一区二| 欧美国产一区在线| 国产午夜伦鲁鲁| 欧美久久亚洲| 日韩在线观看免费高清完整版| 欧美日韩综合在线观看| 国产成人免费在线观看不卡| 亚洲精品视频一二三| 成人av观看| 精品对白一区国产伦| 午夜免费激情视频| 毛片不卡一区二区| 欧洲在线视频一区| 中文字幕一区久| 亚洲国产精品热久久| 99视频只有精品| 久久精品免费观看| 日韩av电影免费播放| 蜜桃视频www网站在线观看| 日韩一二三区视频| 午夜剧场免费在线观看| 美国毛片一区二区| 亚洲国产日韩欧美| 秋霞国产精品| 国产一区二区免费| 久久久黄色大片| 91丨九色porny丨蝌蚪| 久操网在线观看| 88久久精品| 欧美大片免费看| www.久久精品.com| 亚洲精品国产一区二区精华液| 男人的天堂最新网址| 欧美疯狂party性派对| 国产精品视频久久久久| 成黄免费在线| 欧美日韩免费观看一区三区| 九九九视频在线观看| 日韩成人午夜精品| 四虎永久在线精品免费一区二区| 亚洲一区二区三区四区| 国产亚洲精品综合一区91| 无码人妻av免费一区二区三区 | 精品无码人妻一区二区三区品| 国产精品综合网| 日韩人妻一区二区三区蜜桃视频| 欧美三级一区| 欧美老肥婆性猛交视频| www.狠狠干| 欧美日韩国产页| 亚洲欧美色图视频| 日韩精品免费视频人成| 亚洲欧洲一区二区| 精品视频一区二区三区| 久久久久久成人精品| 亚洲av电影一区| 欧美自拍偷拍一区| 婷婷社区五月天| 丁香激情综合国产| 国产超级av在线| 日韩久久精品网| 亚洲伊人成综合成人网| gogo高清在线播放免费| 国产偷亚洲偷欧美偷精品| 中文字幕天堂在线| 亚洲欧美日韩系列| 97香蕉碰碰人妻国产欧美| 久久久久久一区二区| 中文字幕不卡每日更新1区2区| 国产一区二区三区亚洲综合| 国内精品国产三级国产在线专| 九色在线观看| 欧美一级日韩免费不卡| 中文字幕在线字幕中文| 日本一区二区三区四区在线视频| 三级av免费看| 亚洲综合电影一区二区三区| 在线看无码的免费网站| 极品尤物一区| 国产一区二区视频在线观看| а_天堂中文在线| 在线观看欧美成人| 亚洲精品无码久久久| 色国产精品一区在线观看| 成人免费精品动漫网站| 91女神在线视频| 国产欧美精品一二三| 午夜在线视频观看日韩17c| 日日噜噜噜夜夜爽爽| 欧美日韩一区二区三区在线电影| 国产裸体写真av一区二区| аⅴ资源天堂资源库在线| 丝袜亚洲欧美日韩综合| 天堂av网在线| 日韩欧美一级在线播放| 成人黄色片在线观看| 亚洲不卡av一区二区三区| 91香蕉国产视频| 久久综合av免费| 亚洲 自拍 另类 欧美 丝袜| 日韩av一级片| 黄色av网址在线播放| 亚洲欧美伊人| 亚洲在线不卡| 国产一区二区三区91| 国产精品一区二区三区四区五区| 日本一区二区三区中文字幕| 日韩av不卡电影| 草草在线观看| 欧美国产在线电影| 免费黄色网页在线观看| 中文在线不卡视频| 国产尤物视频在线| 精品视频久久久久久久| 黄色小视频免费在线观看| 欧美一区午夜视频在线观看| 中文字幕人妻一区二区在线视频| 欧美日韩亚洲91| 日韩成人免费在线视频| 亚洲一区二区三区在线看| 永久免费看mv网站入口| 国产精品免费久久久久| 日本精品在线观看视频| 久久久99久久| 蜜桃传媒一区二区亚洲av| 99精品一区二区三区| 亚洲自拍偷拍精品| 成人久久18免费网站麻豆| 乱码一区二区三区| 国产成人免费视频网站| 潘金莲一级淫片aaaaa| 久久99精品一区二区三区| 激情五月俺来也| 麻豆91精品91久久久的内涵| 久久久久久久片| 日韩成人一级大片| 九九热在线免费| 秋霞午夜鲁丝一区二区老狼| 黄色在线视频网| 久久精品国产在热久久| www.国产视频.com| 国产综合色在线视频区| 天天干天天曰天天操| 国产成人啪午夜精品网站男同| 蜜桃视频无码区在线观看| 成人黄色在线网站| 精品黑人一区二区三区观看时间| 久久综合久久综合九色| 亚洲av无码国产精品麻豆天美| 久久久99精品免费观看| 国产一区二区三区精品在线| 国产精品久久久久久久久免费桃花 | 欧美男gay| 午夜午夜精品一区二区三区文| 欧美日韩黑人| 国产四区在线观看| 黄色亚洲精品| 欧美日韩亚洲第一| 日本aⅴ免费视频一区二区三区| 国产精品拍拍拍| 国产原创一区二区三区| 在线精品视频播放| 91麻豆产精品久久久久久| wwwww黄色| 一区二区三区不卡视频在线观看| 国产精品成人国产乱| 色婷婷一区二区三区四区| 亚洲系列在线观看| 欧美va亚洲va在线观看蝴蝶网| 天天射,天天干| 色yeye香蕉凹凸一区二区av| 日本片在线观看| 国产精品1234| 日本一区二区乱| 欧美成人一区二区在线| 婷婷综合五月| 男人和女人啪啪网站| 久久精品国产免费| 国产黄色三级网站| 国产精品卡一卡二| 国产精品成人aaaa在线| 欧美群妇大交群的观看方式| 欧美一级片免费| 综合久久五月天| 成年女人在线看片| 成人免费福利在线| 小嫩嫩12欧美| 国产91在线亚洲| 免费在线观看成人| 久久久国产精品无码| 亚洲天堂精品在线观看| 国产无套丰满白嫩对白| 欧美一区二区福利视频| 国产成人天天5g影院在线观看| 久久久久久国产精品三级玉女聊斋 | 亚洲一区图片| 美女被艹视频网站| 国产日产亚洲精品系列| 国产精品a成v人在线播放| 在线成人小视频| 成人在线高清视频| 91精品国产777在线观看| 久久99成人| 亚洲欧美精品在线观看| 国产日韩欧美一区| 色诱av手机版| 1024国产精品| 国产裸体美女永久免费无遮挡| 亚洲国产日韩一区| 污污片在线免费视频| 成人国产精品久久久久久亚洲| 国产精品午夜一区二区三区| 国产精品久久..4399| 国产精品一区二区男女羞羞无遮挡| 三年中国中文观看免费播放| 一本久久a久久免费精品不卡| 欧美一级在线免费观看| 欧美大片欧美激情性色a∨久久| 婷婷精品久久久久久久久久不卡| 久久精品国产精品青草色艺| 一区福利视频| 极品白嫩少妇无套内谢| 亚洲精品一二三| 91无套直看片红桃| 最近2019免费中文字幕视频三| 欧美三级网址| 青娱乐国产91| 久色成人在线| 免费一级做a爰片久久毛片潮| 欧美午夜视频在线观看| 亚州av在线播放| 97成人在线视频| 欧洲精品一区| 国产免费成人在线| 久久久精品免费免费| 欧美一区二区三区网站| 亚洲人午夜色婷婷| 自拍偷自拍亚洲精品被多人伦好爽| 久久国产精品久久| 母乳一区在线观看| 级毛片内射视频| 在线观看国产一区二区| 国产综合在线观看| 国产精品久久中文| 色综合天天爱| 97免费公开视频| 亚洲国产精品精华液网站| 四虎免费在线观看| 欧美中在线观看| av伊人久久| 午夜激情影院在线观看| 亚洲老妇xxxxxx| 刘亦菲毛片一区二区三区| 欧美性在线观看| 欧美呦呦网站| 日本在线播放一区二区| 亚洲精品国产成人久久av盗摄 | 日韩中文字幕无砖| 国产精品一线二线三线| 久久综合视频网| 亚洲一级在线播放| 欧美日本亚洲视频| 午夜先锋成人动漫在线| 日本人视频jizz页码69| 亚洲免费观看高清完整版在线 | 国产精品免费入口| 国产精品午夜免费| 国产三级在线观看视频| 午夜精品一区二区三区在线视 | 99久久久精品视频| 91老师片黄在线观看| 在线视频1卡二卡三卡| 九九热精品视频在线播放| 色天下一区二区三区| 最新中文字幕免费视频| 一区二区三区丝袜| 加勒比一区二区三区在线| 成人在线国产精品| 国产欧美日韩一级| 国产喷水在线观看| 日韩成人av网址| 高清久久一区| 亚洲人成色77777| 亚洲黄色尤物视频| 国产视频精选在线| 国产一区福利视频| 国产综合色产在线精品| 三级网站在线播放| 欧美精品福利在线| 日韩欧美高清| 国产特黄级aaaaa片免|