亚洲有码Av一区二区三区_国产高清啪啪免费视频_69色视频国产_国产成人人人爆出白浆_国产精品自在线拍国_一本久久伊人热热精品无码_午夜性刺激在线看免费带字幕_助力高品质欧美狂喷水_亚洲精品日韩无码_精品无码一区二区三区蜜臀_麻豆高清国产AV_熟妇人素无码中文字幕_亚洲a级片在线观看_国产欧美日韩三区_99国产成人高清在线观看

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營(yíng)的一線(xiàn)實(shí)戰(zhàn)洞察。

前后端JSON交互實(shí)戰(zhàn):從序列化配置到線(xiàn)上排查全指南

前后端JSON交互實(shí)戰(zhàn):從序列化配置到線(xiàn)上排查全指南 很長(zhǎng)一段時(shí)間里我前后端分離的項(xiàng)目一多就發(fā)現(xiàn)一個(gè)特別有意思的現(xiàn)象兩邊同事明明都覺(jué)得自己沒(méi)寫(xiě)錯(cuò)接口一聯(lián)調(diào)就開(kāi)始扯皮。前端說(shuō)后端接口返回的JSON字段對(duì)不上后端說(shuō)前端傳的JSON格式我解析不了。這類(lèi)問(wèn)題聽(tīng)上去是小事可一旦進(jìn)入線(xiàn)上輕則功能白屏重則數(shù)據(jù)錯(cuò)亂。所以后來(lái)我專(zhuān)門(mén)把JSON交互處理這套東西整理成了一套筆記這次干脆把筆記改寫(xiě)成一篇可以直接拿去參考的實(shí)操文章。這篇文章圍繞的就是一件事前后端之間、服務(wù)與服務(wù)之間的JSON數(shù)據(jù)到底怎么做到“發(fā)得出去、收得回來(lái)、兩邊都看得懂”。我會(huì)從JSON的本質(zhì)、Java里的JSON處理庫(kù)選型、Spring Boot中JSON交互的落地配置一直聊到自定義序列化器和線(xiàn)上排查手段。內(nèi)容不算難但信息量不小適合剛接觸接口開(kāi)發(fā)的初學(xué)者也適合被JSON解析問(wèn)題折磨過(guò)、想系統(tǒng)梳理一遍的后端開(kāi)發(fā)。1. 從一次前后端聯(lián)調(diào)事故說(shuō)起JSON交互到底卡在哪1.1 前后端各說(shuō)各話(huà)的典型現(xiàn)場(chǎng)我印象很深的一次事故發(fā)生在某電商促銷(xiāo)項(xiàng)目聯(lián)調(diào)階段。后端寫(xiě)了一個(gè)商品詳情的接口返回的是這樣的結(jié)構(gòu){ code: 200, data: { goodsId: 12345, goodsName: 某品牌保溫杯, createTime: 1719820800000 }, msg: success }結(jié)果前端拿著這個(gè)JSON直接懵了我要的商品名是goodsName你給我的字段倒是這個(gè)可createTime為什么是一串?dāng)?shù)字我們頁(yè)面上要顯示“2024-07-01 12:00:00”這串毫秒時(shí)間戳我怎么展示后端同事也很委屈數(shù)據(jù)庫(kù)存的本來(lái)就是datetime我用接口工具測(cè)的時(shí)候看到的也是正常時(shí)間啊怎么一傳到前端就變成數(shù)字了這個(gè)場(chǎng)景各位寫(xiě)過(guò)前后端分離項(xiàng)目的朋友應(yīng)該都不陌生。問(wèn)題根本不在“誰(shuí)對(duì)誰(shuí)錯(cuò)”而是兩邊的數(shù)據(jù)契約沒(méi)有對(duì)齊。后端返回的是Java對(duì)象序列化之后的JSON前端看到的是JSON解析之后的對(duì)象中間經(jīng)過(guò)序列化和反序列化這兩道工序只要有一道工序的配置不一致看到的東西就不一樣。1.2 JSON交互的本質(zhì)一份兩端共同遵守的協(xié)議我把JSON交互拆成三個(gè)關(guān)鍵詞結(jié)構(gòu)約定、序列化規(guī)則、解析規(guī)則。結(jié)構(gòu)約定是雙方對(duì)字段名、嵌套層級(jí)、數(shù)據(jù)類(lèi)型達(dá)成的一致意見(jiàn)序列化規(guī)則是后端把Java對(duì)象變成JSON字符串時(shí)如何轉(zhuǎn)換類(lèi)型和格式解析規(guī)則是前端或下游服務(wù)拿到JSON字符串后如何還原成自己需要的對(duì)象。三者缺一個(gè)交互就會(huì)出現(xiàn)偏差。舉個(gè)最直觀的說(shuō)法JSON交互就像兩個(gè)人約定用同一種語(yǔ)言寫(xiě)信。約定用中文是結(jié)構(gòu)約定按語(yǔ)法把想法寫(xiě)成句子是序列化對(duì)方讀到句子后理解意思是解析。如果寫(xiě)信的人用中文但收信的人以為信里全是英文或者寫(xiě)信人把日期寫(xiě)成“7月1日”收信人卻當(dāng)成“1月7日”信息就悄悄變了。所以我在項(xiàng)目里定了一個(gè)規(guī)矩任何接口在動(dòng)工前先寫(xiě)一份字段對(duì)照表。字段叫什么名、什么類(lèi)型、空值怎么處理、時(shí)間用什么格式、嵌套多深全部寫(xiě)清楚。這個(gè)習(xí)慣看起來(lái)麻煩卻能省掉后面大量“我這邊對(duì)你那邊錯(cuò)”的爭(zhēng)論。1.3 交互處理的最小鏈路拆解一次完整的JSON交互鏈路大概是這樣的后端收到HTTP請(qǐng)求取出請(qǐng)求體里的JSON字符串交給反序列化器轉(zhuǎn)成Java對(duì)象然后業(yè)務(wù)邏輯處理再把返回結(jié)果交給序列化器轉(zhuǎn)成JSON字符串最后寫(xiě)進(jìn)HTTP響應(yīng)。前端拿到響應(yīng)后再做一次JSON解析。用代碼表達(dá)就是// 請(qǐng)求側(cè)字符串 - Java對(duì)象 String requestJson ...; ObjectMapper mapper new ObjectMapper(); GoodsQuery query mapper.readValue(requestJson, GoodsQuery.class); // 響應(yīng)側(cè)Java對(duì)象 - 字符串 GoodsDetail detail goodsService.queryDetail(query); String responseJson mapper.writeValueAsString(detail);看起來(lái)只有兩行核心代碼但里面藏著大量細(xì)節(jié)日期類(lèi)型轉(zhuǎn)成什么格式、枚舉轉(zhuǎn)成字符串還是序號(hào)、數(shù)組空的時(shí)候是輸出[]還是null、下劃線(xiàn)命名的字段和駝峰命名的字段怎么映射、對(duì)象里有循環(huán)引用怎么辦……每一個(gè)細(xì)節(jié)都可能成為線(xiàn)上事故的導(dǎo)火索。2. 別說(shuō)“不就轉(zhuǎn)一下JSON嘛”數(shù)據(jù)形態(tài)轉(zhuǎn)換里的隱性細(xì)節(jié)2.1 三種數(shù)據(jù)形態(tài)閱讀態(tài)、內(nèi)存態(tài)、傳輸態(tài)我經(jīng)常跟新人強(qiáng)調(diào)一個(gè)概念JSON在整套交互流程里并不是同一個(gè)東西。它可以分成三種形態(tài)來(lái)看。第一種是閱讀態(tài)也就是你在接口文檔、網(wǎng)頁(yè)格式化工具里看到的那個(gè)文本帶縮進(jìn)、帶引號(hào)人能直接看懂。第二種是內(nèi)存態(tài)比如Java里那個(gè)帶著屬性、類(lèi)型、嵌套關(guān)系的對(duì)象它活在JVM堆里。第三種是傳輸態(tài)就是HTTP請(qǐng)求體或響應(yīng)體里實(shí)際的字節(jié)流可能是被壓縮過(guò)的、被轉(zhuǎn)義過(guò)的、按某種編碼傳輸?shù)摹:芏嘟馕鰡?wèn)題本質(zhì)上就是這三種狀態(tài)之間轉(zhuǎn)換時(shí)出了問(wèn)題。比如后端把對(duì)象轉(zhuǎn)成字符串時(shí)沒(méi)配置日期格式內(nèi)存態(tài)里好好的LocalDateTime到傳輸態(tài)就變成了時(shí)間戳再比如前端給后端傳JSON中間經(jīng)過(guò)網(wǎng)關(guān)時(shí)被重新編碼中文字符出現(xiàn)亂碼那就是傳輸態(tài)這里出了問(wèn)題。認(rèn)清這三種形態(tài)之后排查問(wèn)題會(huì)有一個(gè)很清晰的方向先看問(wèn)題是出在序列化、傳輸還是反序列化。不要一上來(lái)就懷疑代碼邏輯寫(xiě)錯(cuò)了。2.2 String轉(zhuǎn)對(duì)象和對(duì)象轉(zhuǎn)String遠(yuǎn)不是new一個(gè)ObjectMapper很多新手覺(jué)得JSON轉(zhuǎn)換不就是new ObjectMapper()然后調(diào)用兩個(gè)方法嗎表面上沒(méi)錯(cuò)但一旦牽扯到復(fù)雜類(lèi)型事情就沒(méi)那么簡(jiǎn)單。舉個(gè)例子前端傳過(guò)來(lái)一個(gè)JSON數(shù)組[ {userId: 1, userName: A同學(xué)}, {userId: 2, userName: B同學(xué)} ]后端如果直接寫(xiě)ListUser userList mapper.readValue(json, List.class);這段代碼能跑但運(yùn)行到userList.get(0).getUserName()的時(shí)候大概率會(huì)報(bào)ClassCastException。原因很簡(jiǎn)單List.class只能告訴反序列化器“目標(biāo)是List”卻沒(méi)法告訴它“List里裝的是User”。泛型信息在運(yùn)行時(shí)被擦除了Jackson拿到的只是一個(gè)泛型List它只能按LinkedHashMap來(lái)解析。正確寫(xiě)法是用TypeReference把泛型帶進(jìn)去ListUser userList mapper.readValue(json, new TypeReferenceListUser() {});這個(gè)坑幾乎所有寫(xiě)過(guò)Java接口的人都踩過(guò)。我當(dāng)時(shí)給新人講的時(shí)候打了個(gè)比方你要快遞員送一箱蘋(píng)果光說(shuō)“送一箱”是不夠的得說(shuō)清楚箱子里是什么。List.class就是那個(gè)沒(méi)說(shuō)清楚的“一箱”而new TypeReferenceListUser() {}就是“一箱蘋(píng)果”。2.3 為什么空值、特殊字符在轉(zhuǎn)換中最容易出問(wèn)題序列化和反序列化里最容易出問(wèn)題的不是常規(guī)數(shù)據(jù)而是邊界數(shù)據(jù)??罩稻褪堑湫?。后端有一個(gè)對(duì)象某個(gè)字段是null默認(rèn)序列化之后這個(gè)字段可能直接消失也可能輸出null取決于全局配置。前端如果寫(xiě)死了要取這個(gè)字段拿到的卻是undefined頁(yè)面上可能就渲染異常。特殊字符是另一個(gè)重災(zāi)區(qū)。JSON字符串里如果包含換行符、引號(hào)、反斜杠序列化時(shí)必須正確轉(zhuǎn)義否則生成的JSON就是非法JSON前端一解析就報(bào)錯(cuò)。更隱蔽的是那些不可見(jiàn)字符比如某些業(yè)務(wù)系統(tǒng)從別的地方復(fù)制過(guò)來(lái)的文本里帶了特殊空白符肉眼完全看不出來(lái)但JSON解析器對(duì)某些字符的處理邏輯并不一致同一個(gè)字符串在A庫(kù)解析成功在B庫(kù)解析失敗。我對(duì)這個(gè)問(wèn)題的處理思路很樸素在所有對(duì)外接口的序列化配置里把空值處理策略顯式地定好要么統(tǒng)一輸出null要么統(tǒng)一忽略同時(shí)在接口測(cè)試階段就覆蓋“字符串帶引號(hào)、帶換行、帶emoji”這類(lèi)用例別等上線(xiàn)了再由用戶(hù)幫我們發(fā)現(xiàn)。3. 三個(gè)主流JSON庫(kù)的取舍選型不該只看百度搜到哪篇3.1 三庫(kù)差異對(duì)照我實(shí)際用下來(lái)的感受Java生態(tài)里處理JSON的庫(kù)翻來(lái)覆去就那么幾個(gè)Spring Boot默認(rèn)自帶的Jackson、國(guó)內(nèi)用得多的Fastjson、老牌的Gson。網(wǎng)上關(guān)于它們誰(shuí)快的文章一抓一大把但真正到項(xiàng)目選型時(shí)我更看重的是穩(wěn)定性和可控性。先說(shuō)我自己的使用感受。Jackson是Spring Boot的默認(rèn)選擇這意味著在Spring項(xiàng)目里引入它幾乎零成本而且Spring Boot的自動(dòng)配置已經(jīng)幫你把序列化器接好了注解支持也最豐富。Gson是Google出品的API設(shè)計(jì)很簡(jiǎn)潔new Gson().toJson(obj)和fromJson兩個(gè)方法搞定大部分場(chǎng)景但功能深度不如Jackson。Fastjson最大的特點(diǎn)是序列化性能在某些場(chǎng)景下確實(shí)快API寫(xiě)起來(lái)也很順手但歷史上暴露過(guò)的安全漏洞讓我在核心鏈路上不太敢用它。我做過(guò)的幾個(gè)老項(xiàng)目里這三種庫(kù)都出現(xiàn)過(guò)。有些項(xiàng)目因?yàn)闅v史原因從Fastjson切到過(guò)Jackson單純是因?yàn)橥ㄓ眯愿谩⑸鐓^(qū)維護(hù)頻率更高。Gson我一般只用在一些自己寫(xiě)的小工具里圖它輕便。3.2 性能不是唯一標(biāo)準(zhǔn)安全性和可控性更關(guān)鍵如果你去搜“Fastjson為什么快”會(huì)看到一堆壓測(cè)數(shù)據(jù)確實(shí)在某些場(chǎng)景下它的表現(xiàn)不錯(cuò)。但我選JSON庫(kù)從來(lái)不把性能當(dāng)成第一指標(biāo)因?yàn)閷?duì)于絕大多數(shù)業(yè)務(wù)系統(tǒng)來(lái)說(shuō)JSON序列化根本不在性能瓶頸上真正耗時(shí)的是數(shù)據(jù)庫(kù)查詢(xún)和遠(yuǎn)程調(diào)用。我更在意的是三點(diǎn)。第一是否支持自定義序列化器和反序列化器因?yàn)闃I(yè)務(wù)里總有一些特殊字段需要特殊處理比如脫敏。第二對(duì)未知字段、循環(huán)引用、深層嵌套這類(lèi)極端情況的默認(rèn)行為是否可控能不能通過(guò)配置兜住。第三框架自動(dòng)配置的深度換句話(huà)說(shuō)就是我是不是只寫(xiě)一個(gè)注解就能讓整個(gè)項(xiàng)目的JSON交互行為發(fā)生改變。拿Jackson舉例它支持JsonIgnore、JsonProperty、JsonFormat、JsonSerialize、JsonDeserialize幾乎覆蓋了我遇到過(guò)的所有需求。Gson也可以用TypeAdapter做到類(lèi)似效果但寫(xiě)起來(lái)會(huì)繁瑣不少。3.3 一個(gè)項(xiàng)目究竟該怎么選我的選型建議是這樣的如果是Spring Boot新項(xiàng)目直接用Jackson沒(méi)必要額外引庫(kù)因?yàn)镴ackson已經(jīng)深度集成在Spring Boot的MVC里日期格式化、空值處理、字段命名策略都能通過(guò)配置文件統(tǒng)一管理如果是一個(gè)老項(xiàng)目想重構(gòu)且現(xiàn)有代碼大量使用了Fastjson的API也不要急著全換一步一步把高危鏈路先切到Jackson測(cè)試穩(wěn)定后再推進(jìn)如果只是寫(xiě)個(gè)腳本或者做本地小工具Gson完全夠用。這里有個(gè)特別容易踩的雷一個(gè)項(xiàng)目里同時(shí)引了多個(gè)JSON庫(kù)平時(shí)各用各的看起來(lái)相安無(wú)事等某一天工具類(lèi)里混用了這兩個(gè)庫(kù)的注解和API序列化結(jié)果就會(huì)出現(xiàn)莫名其妙的差異。項(xiàng)目里最好統(tǒng)一一個(gè)主JSON庫(kù)工具類(lèi)只封裝這一個(gè)庫(kù)的API別給自己留混用的機(jī)會(huì)。4. Spring Boot里JSON交互的落地姿勢(shì)與全局配置4.1 RequestBody和ResponseBody到底做了什么在Spring Boot的Web層JSON交互最核心的就是兩個(gè)注解RequestBody和ResponseBody。很多新手只是會(huì)用但并不完全清楚它們背后的機(jī)制。RequestBody作用在方法參數(shù)上告訴Spring把HTTP請(qǐng)求體里的JSON字符串反序列化成后面的Java對(duì)象。這個(gè)過(guò)程中Spring用的就是當(dāng)前容器里注冊(cè)的MappingJackson2HttpMessageConverter消息轉(zhuǎn)換器負(fù)責(zé)把請(qǐng)求體字符串轉(zhuǎn)成對(duì)象。ResponseBody作用在返回值上或者直接加在類(lèi)上讓所有方法生效告訴Spring把Java對(duì)象序列化成JSON字符串寫(xiě)進(jìn)響應(yīng)體。用RestController就相當(dāng)于在類(lèi)上同時(shí)加上了Controller和ResponseBody這也是現(xiàn)在最主流的寫(xiě)法。如果你遇到一個(gè)問(wèn)題后端寫(xiě)好的RequestBody User user前端傳了JSON過(guò)來(lái)但user對(duì)象里某些字段為null。不要急著懷疑前端先想想是不是前后端字段名沒(méi)對(duì)上。默認(rèn)情況下Jackson是把JSON字段名和Java屬性名做一一映射的前端傳的userName后端對(duì)象里屬性也是userName才能正確對(duì)應(yīng)。如果前端習(xí)慣傳下劃線(xiàn)風(fēng)格user_name后端就得加全局配置或者用JsonProperty(user_name)做映射。4.2 全局Jackson配置日期、空值、命名策略一網(wǎng)打盡全局配置的意義在于你不必在每個(gè)字段上都寫(xiě)注解只需要在配置文件里聲明一套默認(rèn)策略就能讓所有接口的JSON行為統(tǒng)一。我用Spring Boot時(shí)最常配置的幾項(xiàng)如下spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT8 default-property-inclusion: non_null serialization: write-dates-as-timestamps: false deserialization: fail-on-unknown-properties: false第一行指定日期格式為yyyy-MM-dd HH:mm:ss第二行指定時(shí)區(qū)為東八區(qū)這一點(diǎn)特別重要因?yàn)槿绻愕姆?wù)器在別的時(shí)區(qū)不指定時(shí)區(qū)會(huì)導(dǎo)致日期序列化出來(lái)差8個(gè)小時(shí)第三行表示序列化時(shí)忽略值為null的字段第四行讓日期序列化時(shí)不輸出時(shí)間戳而是輸出格式化字符串第五行是反序列化時(shí)遇到未知字段不報(bào)錯(cuò)這對(duì)于前端多傳冗余字段的情況很友好。日期格式在這個(gè)配置里是全局生效的但業(yè)務(wù)里總有幾個(gè)接口需要用不同的日期格式這時(shí)候可以用JsonFormat在字段上覆蓋全局配置。記住一個(gè)原則全局定默認(rèn)局部做覆蓋注釋里說(shuō)清楚為什么覆蓋。4.3 統(tǒng)一響應(yīng)包裝把“成功/失敗”的反饋規(guī)則先定下來(lái)JSON交互里另一個(gè)被忽略但很重要的問(wèn)題就是響應(yīng)結(jié)構(gòu)不統(tǒng)一。有的接口成功時(shí)返回的是一個(gè)對(duì)象失敗時(shí)返回的是一個(gè)字符串或者成功和失敗字段的嵌套層級(jí)完全不同。前端對(duì)接起來(lái)就非常痛苦每個(gè)接口都要單獨(dú)寫(xiě)解析邏輯。我習(xí)慣在項(xiàng)目里做一個(gè)統(tǒng)一的響應(yīng)包裝類(lèi)類(lèi)似下面這樣public class ApiResultT { private Integer code; private String message; private T data; public static T ApiResultT success(T data) { ... } public static T ApiResultT error(Integer code, String message) { ... } }所有接口的返回值都包裝成ApiResultTcode表示業(yè)務(wù)狀態(tài)碼message是給前端展示的提示信息data是真正的業(yè)務(wù)數(shù)據(jù)。這樣前端只需要判斷code再?zèng)Q定取message還是data規(guī)則就固定下來(lái)了。統(tǒng)一包裝看起來(lái)是件小事但它在整個(gè)團(tuán)隊(duì)里建立的是一套交互契約。每次開(kāi)會(huì)討論接口時(shí)大家只需要關(guān)心data里是什么而不需要擔(dān)心外面那層殼今天會(huì)不會(huì)變。5. 實(shí)戰(zhàn)踩坑清單日期、循環(huán)引用、泛型丟失、中文亂碼5.1 日期格式不一致典型的“兩邊都對(duì)合不上”接著開(kāi)頭那個(gè)案例繼續(xù)說(shuō)。日期格式不一致是JSON交互里出現(xiàn)頻率最高的坑而且它的結(jié)構(gòu)非常一致后端認(rèn)為自己在序列化時(shí)輸出了格式化字符串前端看到的是時(shí)間戳或者前端給后端傳了一個(gè)2024-07-01 12:00:00后端反序列化時(shí)也按這個(gè)格式解析但由于時(shí)區(qū)不對(duì)入庫(kù)時(shí)間成了2024-06-30 04:00:00。排查日期問(wèn)題的順序我一般是先看序列化配置里有沒(méi)有指定格式和時(shí)區(qū)再看字段上有沒(méi)有被JsonFormat單獨(dú)覆蓋最后看傳輸過(guò)程中是否有中間層重新處理了日期字段。有一次我們排查了很久最后發(fā)現(xiàn)是網(wǎng)關(guān)層對(duì)響應(yīng)體做了字符串替換把時(shí)間格式里的斜杠替換成了橫杠結(jié)果后端看到的是橫杠格式的字符串再次序列化時(shí)格式全亂了。所以排查要覆蓋鏈路中的每一個(gè)節(jié)點(diǎn)不能只看服務(wù)端。5.2 循環(huán)引用和懶加載一序列化就整頁(yè)報(bào)錯(cuò)循環(huán)引用是后端對(duì)象序列化中最讓人頭疼的問(wèn)題。舉個(gè)常見(jiàn)的場(chǎng)景一個(gè)訂單對(duì)象里有用戶(hù)對(duì)象用戶(hù)對(duì)象里又有一個(gè)訂單列表序列化訂單時(shí)Jackson發(fā)現(xiàn)訂單里有用戶(hù)用戶(hù)又有訂單訂單里又有用戶(hù)……如果不做任何限制它就會(huì)無(wú)限嵌套下去最后棧溢出。解決循環(huán)引用有三個(gè)方向。第一個(gè)是業(yè)務(wù)上明確不需要閉環(huán)直接在某一端用JsonIgnore把不需要的字段忽略掉第二個(gè)是用JsonIdentityInfo讓相同對(duì)象在序列化時(shí)以ID引用而不是展開(kāi)完整對(duì)象第三個(gè)是從設(shè)計(jì)上避免雙向?qū)ο笾苯颖┞督o前端改用DTO數(shù)據(jù)傳輸對(duì)象只返回前端需要的那幾個(gè)字段。還有一個(gè)讓很多人踩過(guò)的坑是Hibernate的懶加載。一個(gè)實(shí)體類(lèi)里有OneToMany的關(guān)系屬性沒(méi)被訪(fǎng)問(wèn)時(shí)它是一個(gè)代理對(duì)象直接序列化時(shí)會(huì)觸發(fā)LazyInitializationException。這種情況我一般也用DTO解決顯式地把需要的數(shù)據(jù)查出來(lái)再組裝成返回對(duì)象而不是試圖把JPA實(shí)體直接丟給序列化器。5.3 泛型與類(lèi)型擦除List 接口返回前端拿不到全字段前面提到了TypeReference這里展開(kāi)講一個(gè)實(shí)際案例。有個(gè)接口返回ListUser實(shí)現(xiàn)時(shí)直接用了List.class作為反序列化目標(biāo)。結(jié)果前端拿到數(shù)據(jù)后發(fā)現(xiàn)user對(duì)象里混著一堆LinkedHashMap的結(jié)構(gòu)所有的字段都變成了map.get(xxx)的取值方式。前端說(shuō)接口文檔寫(xiě)得不對(duì)后端說(shuō)我返回的就是數(shù)組。兩邊都很委屈但根源只有一個(gè)反序列化時(shí)泛型信息丟失。Jackson在反序列化時(shí)如果無(wú)法得知目標(biāo)元素類(lèi)型只會(huì)按照最通用的Map結(jié)構(gòu)處理。這個(gè)問(wèn)題不光影響List任何帶泛型的類(lèi)型都會(huì)遇到比如MapString, User、PageResultUser處理方式都一樣要么用TypeReference要么在繼承類(lèi)時(shí)把泛型固定下來(lái)比如定義一個(gè)UserList extends ArrayListUser這是個(gè)很偏門(mén)但有效的技巧。5.4 中文亂碼與特殊字符Tomcat配置和轉(zhuǎn)義策略中文亂碼在JSON交互里雖然不像以前那么常見(jiàn)但一旦出現(xiàn)就特別難排查因?yàn)樗皇呛蠖舜a的問(wèn)題而是整個(gè)鏈路的編碼不統(tǒng)一。HTTP請(qǐng)求和響應(yīng)都有各自的字符集如果服務(wù)端返回Content-Type: application/json;charsetUTF-8而中間某層把它改成了別的編碼中文就會(huì)變成亂碼。Spring Boot里可以這樣顯式地設(shè)置響應(yīng)編碼server: servlet: encoding: charset: UTF-8 enabled: true force: trueforce: true表示強(qiáng)制所有請(qǐng)求和響應(yīng)都使用UTF-8避免因?yàn)榭蛻?hù)端沒(méi)帶編碼參數(shù)導(dǎo)致的亂碼。另外還要注意JSON字符串本身對(duì)控制字符是有限制的比如\u0000這類(lèi)字符不能被直接放進(jìn)JSON字符串。如果業(yè)務(wù)數(shù)據(jù)里可能包含這類(lèi)字符序列化時(shí)往往會(huì)被丟棄或轉(zhuǎn)義兩端看到的文本就不同。對(duì)于包含接口日志的數(shù)據(jù)我建議在寫(xiě)日志時(shí)把請(qǐng)求體和響應(yīng)體做一次JSON美化輸出同時(shí)打印轉(zhuǎn)義后的可見(jiàn)字符串這樣定位問(wèn)題才不會(huì)被特殊字符干擾。6. 自定義序列化器把敏感字段的“對(duì)外長(zhǎng)相”攥在自己手里6.1 什么場(chǎng)景值得寫(xiě)一個(gè)自定義序列化器全局配置解決的是通用問(wèn)題但業(yè)務(wù)里總有那么幾個(gè)字段不按常理出牌。最常見(jiàn)的場(chǎng)景就是數(shù)據(jù)脫敏。比如用戶(hù)手機(jī)號(hào)數(shù)據(jù)庫(kù)里存的是13812345678接口返回給前端時(shí)頁(yè)面可能只需要展示138****5678。這個(gè)需求如果用JsonIgnore把字段整個(gè)忽略掉前端就拿不到數(shù)據(jù)了如果讓前端自己截?cái)嗄堑扔诎衙撁暨壿媮G給了用戶(hù)也不合理。更合理的做法是數(shù)據(jù)庫(kù)存原始數(shù)據(jù)接口按場(chǎng)景決定“對(duì)外長(zhǎng)相”。后端默認(rèn)配置下敏感字段可以統(tǒng)一掛一個(gè)自定義序列化器序列化時(shí)自動(dòng)脫敏。這樣業(yè)務(wù)代碼里不需要寫(xiě)任何脫敏邏輯前端拿到手的就是已經(jīng)處理好的數(shù)據(jù)。6.2 手機(jī)號(hào)脫敏字段一個(gè)10行的自定義序列化器在Jackson里實(shí)現(xiàn)自定義序列化器很簡(jiǎn)單繼承JsonSerializerT重寫(xiě)serialize方法再用JsonSerialize注解掛到字段上。public class PhoneDesensitizeSerializer extends JsonSerializerString { Override public void serialize(String phone, JsonGenerator gen, SerializerProvider serializers) throws IOException { if (phone null || phone.length() 7) { gen.writeString(phone); return; } gen.writeString(phone.substring(0, 3) **** phone.substring(7)); } } public class UserVO { JsonSerialize(using PhoneDesensitizeSerializer.class) private String phone; }這段代碼的核心是serialize方法判斷手機(jī)號(hào)夠不夠7位不夠就直接輸出夠就把中間四位替換成星號(hào)。字段類(lèi)上掛注解后Jackson在序列化這個(gè)字段時(shí)就會(huì)走進(jìn)這個(gè)邏輯。這個(gè)思路還能延伸到很多地方身份證號(hào)脫敏、郵箱地址脫敏、銀行卡號(hào)脫敏。規(guī)則不同但寫(xiě)法大同小異。我用這個(gè)方式在項(xiàng)目里統(tǒng)一處理過(guò)一批敏感字段效果很好最大的好處是脫敏規(guī)則收斂在序列化器里而不是散落在各個(gè)業(yè)務(wù)方法的if/else里。6.3 自定義反序列化處理前端多態(tài)字段的實(shí)踐自定義反序列化的場(chǎng)景相對(duì)少一些但一遇到就是硬需求。舉個(gè)真實(shí)例子前端有一個(gè)值可能是字符串也可能是字符串?dāng)?shù)組也可能是單個(gè)對(duì)象也可能是對(duì)象數(shù)組。這種不確定的入?yún)⒑蠖巳绻欢x一種類(lèi)型必有一半的請(qǐng)求解析失敗。我的處理方式是在反序列化器里做兼容。繼承JsonDeserializerT重寫(xiě)deserialize先看當(dāng)前JsonToken是什么類(lèi)型如果是VALUE_STRING就按字符串解析如果是START_ARRAY就遍歷數(shù)組把元素收集起來(lái)然后統(tǒng)一返回一個(gè)List結(jié)構(gòu)。public class FlexibleStringListDeserializer extends JsonDeserializerListString { Override public ListString deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { ListString result new ArrayList(); if (p.currentToken() JsonToken.START_ARRAY) { while (p.nextToken() ! JsonToken.END_ARRAY) { result.add(p.getValueAsString()); } } else { result.add(p.getValueAsString()); } return result; } }這種靈活反序列化器能解決接口兼容問(wèn)題但我建議只用在做舊接口兼容、第三方回調(diào)適配這類(lèi)場(chǎng)景。新寫(xiě)的內(nèi)部接口能定死類(lèi)型就定死類(lèi)型別為了省事什么都兼容不然代碼越寫(xiě)越復(fù)雜最后自己都搞不清一個(gè)字段到底有多少種可能性。7. 聯(lián)調(diào)與線(xiàn)上排查我慣用的三板斧7.1 聯(lián)調(diào)期用哪些手段快速驗(yàn)證JSON交互聯(lián)調(diào)階段最容易發(fā)現(xiàn)JSON交互問(wèn)題這時(shí)候我很少直接打開(kāi)瀏覽器看頁(yè)面而是先用接口測(cè)試工具把請(qǐng)求和響應(yīng)分開(kāi)驗(yàn)證。我常用的驗(yàn)證步驟是第一步新建請(qǐng)求寫(xiě)入JSON請(qǐng)求體確認(rèn)HTTP狀態(tài)碼和響應(yīng)結(jié)構(gòu)第二步檢查響應(yīng)JSON里每個(gè)字段的類(lèi)型重點(diǎn)關(guān)注時(shí)間、金額、數(shù)組空值第三步把響應(yīng)JSON復(fù)制到格式化工具里看一眼整體嵌套對(duì)不對(duì)。如果是一個(gè)比較復(fù)雜的JSON結(jié)構(gòu)前端同學(xué)經(jīng)常會(huì)問(wèn)“這個(gè)字段到底是字符串還是數(shù)字”。為了避免這個(gè)溝通成本我習(xí)慣在接口文檔里直接標(biāo)注示例值示例值能寫(xiě)123的字符串還是123的字符串都要寫(xiě)清楚。很多字段歧義本質(zhì)上就是示例值不明確造成的。7.2 線(xiàn)上JSON解析異常日志的定位思路線(xiàn)上環(huán)境沒(méi)有接口測(cè)試工具那么方便所以日志是排查的主通道。JSON解析異常常見(jiàn)報(bào)錯(cuò)有幾種JsonParseException表示請(qǐng)求體根本不是合法JSON多半是前端拼錯(cuò)了字符或者被中間層截?cái)郙ismatchedInputException表示JSON結(jié)構(gòu)合法但類(lèi)型對(duì)不上比如前端傳了字符串后端定義的是數(shù)字InvalidDefinitionException表示序列化目標(biāo)本身有問(wèn)題比如循環(huán)引用、找不到getter方法。我的定位思路是先看異常信息里指向的字段名再拿原始請(qǐng)求體做一次本機(jī)復(fù)現(xiàn)。很多線(xiàn)上解析問(wèn)題本地一復(fù)現(xiàn)就能定位因?yàn)閳?bào)錯(cuò)信息已經(jīng)告訴你字段名了。真正難的是那種“偶發(fā)解析失敗”這種情況多半和特定輸入值有關(guān)比如某個(gè)字符串里帶了換行符某個(gè)字符串特別長(zhǎng)超過(guò)了中間件限制。解決偶發(fā)問(wèn)題的辦法是把請(qǐng)求體完整打到日志里一次復(fù)現(xiàn)就什么都能看出來(lái)。7.3 一次排查經(jīng)歷請(qǐng)求體過(guò)大與嵌套JSON邊界問(wèn)題最后分享一個(gè)印象比較深的排查經(jīng)歷。當(dāng)時(shí)線(xiàn)上有個(gè)接口偶爾報(bào)錯(cuò)錯(cuò)誤信息是“Unexpected character...”但同樣的請(qǐng)求參數(shù)重新提交一次又能成功。從表現(xiàn)看像是數(shù)據(jù)傳輸過(guò)程中內(nèi)容被截?cái)嗔?。查了一圈最后定位到是網(wǎng)關(guān)層對(duì)請(qǐng)求體大小做了限制超過(guò)限制的請(qǐng)求體被攔下一部分后端收到的是半截JSON自然解析失敗。解決方法是調(diào)大請(qǐng)求體限制并在網(wǎng)關(guān)層增加對(duì)Content-Length的校驗(yàn)超長(zhǎng)的請(qǐng)求提前返回明確提示而不是讓它進(jìn)入后端變成一條看不懂的解析異常。這個(gè)案例給我的啟發(fā)是JSON交互問(wèn)題不能只盯著JSON本身還要看承載它的整個(gè)管道。HTTP頭部、網(wǎng)關(guān)配置、代理層、編碼設(shè)置每一層都有可能改動(dòng)JSON的實(shí)際內(nèi)容。排查看鏈路這六個(gè)字是我處理這類(lèi)問(wèn)題最核心的心得。再補(bǔ)充一個(gè)實(shí)際經(jīng)驗(yàn)JSON交互想要少出問(wèn)題接口文檔和前后端契約是最前線(xiàn)的防線(xiàn)。數(shù)據(jù)格式再簡(jiǎn)單也要把示例寫(xiě)清楚字段再多也要統(tǒng)一空值處理。這些東西看起來(lái)算不上核心技術(shù)但真到了線(xiàn)上報(bào)錯(cuò)搶救的時(shí)候每一份清晰的約定都能幫你少點(diǎn)一次應(yīng)急工單。希望這篇文章里梳理的思路能讓你在下次遇到JSON交互問(wèn)題時(shí)手里有一張完整的排查地圖。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
99老司机精品视频在线观看| 成人三级片一区二区三区视频| 国产精品视频麻豆入口| 99re视频在线播放青草| 超碰免费欧美7| 日韩成人电影AV| 日韩精品永久在线观看| 中文字幕高清精品一区| 老熟女阿 国产91| 亚洲天堂日本| 东北老女人的激情视频| 欧美熟妇精品黑人巨大一二三区| 五月天婷婷影院| 午夜影美女日鸡鸡天天视频国产| 久久久国产三级黄色片| 亚洲成人在线高清| 国产精品人人爽人人做可爱福利| 国产一区二区在线播放| 97爱综合| 啊啊啊无码| 欧美在线|亚洲| 无码一区二区三区四区五区六区七区八区九区十区视频 | 久久无码精品| 久草精品在线| 91精品在线播放| 亚洲青青草| 亚洲AV高潮| 色综合中文字幕不卡| 色婷婷狠狠18禁| 欧 美 自 拍 偷 拍| 伊人加勒比| 国产又粗又长视频| 天天看片青娱乐| 91欧美综合在线| 求求你操操我| 啊嗯嗯啊好大好爽| 99999这里都精品| 学生妹天天看| 日本高清一本二本免费不卡| 男人的天堂kva| 俞拍自拍| 国产精品成人午夜福利| 大香蕉中文在线| 欧美日韩亚洲少妇寂寞影院正在播放 | 亚洲国产欧美中文永久| 五月婷色| 亚码激情| 激情综合av| 人妻 欧美 中文| 欧美日本成人一区二区| 亚洲国产成人福利在线观看| 中字乱伦AV| 小泽玛利亚一二三| 欧美久久毛片基地| 亚洲精品1区| 熟妇激情| 久久久久久久久久久久97 | 国产精品青青草| 伊人97色天使| 婷婷五月天无码 | 911粉嫩人妻| 亚洲各类熟们中文字幕| 久久久久精| 精品十三区| 长久操视频| 91日产桃蜜| 中文字幕三四区| gogogo免费高清看中国国语| 亚洲中文字幕精品久久久久久直播| 另类一区| 欧美一品道| 91丝袜人妻| 亚洲一区二区三区春色| 欧美综合骚| 欧美97视频| 欧美黑人与女人91| 午夜福利av电影在线| 91精品丝袜在线观看| 九九九成人| 精品国产91av一区二区三区| 亚洲天堂区| 走光一区92下载| 久久 精品| 亚洲国产ⅴ高清在线观看| 欧美日韩第一页| 91九色丨国产丨爆乳| 久久宗合亚洲| 九九九色| 欧美精品另类人妖xxxx| 人妻人久久精品中文字幕| 尹人免费观看视频在线| 久久一二区四| 日韩图色| 91碰碰| 激情人妻另类| 九九九久久久| 性爱久久| 欧美日韩国产人人| 欧美亚洲日本激情在线| 超碰地址97| 国产路线专区| 破苞ⅩXXX性无码动漫无码| 亚洲精品蜜桃久久久一区二区三区| 日韩无码久久熟女一级片| 人人干人人操人人爱| 在线99热| 天天92av| 观看免费区二区三区二| 精品日日人妻| 丁香婷婷啪啪| 97久久久网站| 91粉芽高清在线一区二区| 欧亚日韩综合精品国产| 激情综合二| 亚洲Av噜噜一区二区三区妖精| 青青在线视频日韩欧美| 嗯嗯,啊啊,国产精品| 色五月av| 一区二区激情国产熟女 | 99rre在线精品99re8| 国产黄色影片在线观看| 五十路熟女工口| 日韩免费a级毛片无码a∨| 日本天天操| 清纯唯美综合亚洲| 五月丁香六月婷| 992大香蕉| 91GD.COM| 综合国产影视三级| com 首页 18岁 禁区 女优 免费 精选 同城 | 五月天人妻综合| 亚洲欧洲日韩国产自在线| 天美传媒Av在线| 亚欧毛片基地国产毛片基地| 国产不卡中文字幕免费avi| 亚洲天堂精品日韩电影| 日韩中文字幕熟妇人妻 | 欧美不在线| 中文字幕视频2区| 欧美影院一区二区三区| 操逼精品视频| 国产精品探花视频| 富女玩鸭子一级毛片| 亚洲色图 欧美热图 清纯唯美 另类自拍 | 日韩乱伦影音先锋| 亚洲色欧| 国产丝袜美女诱惑| 欧美操逼熟女| 老熟女综合网| 啊啊啊啊啊啊啊好爽不要| 多毛小伙内射老太婆| 丝袜高跟澳门91视频| 91操碰| 啊啊啊啊啊啊啊啊视频| 欧美青青视频| 天美传媒av 在线| 国产成人自拍视频视频| 69一区二区三区 | 亚洲性高潮| 国产精品一区二区在钱播放| 国产麻豆福利av在线播放| 久久大香蕉97| 夜夜爽爽夜夜精品视频| 操逼精品视频| 色色色网站| AV在线性爱| 欧美日韩欧美| 午夜精品久久999热蜜桃介男人用| 欧亚日本情色| 日韩少妇丰满亚洲| 开心五月天激情网| 国产成人在线观看综合| 人妻 中文 日韩| 精品免费一区| 国产区在线| 免费网站观看www在线观| 欧美成人性爱视频大全| 手机看片日韩人妻| 女性91网站| 国产日韩美女小穴视频网站不卡| 91少妇通奸网站| 欧美综合加勒比在线| 韩国一级做A片免费的| 午夜操一操| 好吊色青靑草| 久久在肏| 秘书高跟黑色丝袜国产91在线| 97超碰逼| 欧美色997| 欧美日韩性感| 九九久久精品| 国产自偷自拍一区| 人人色人人操在线| 大香网伊人久久综合| 午夜精品久久久久久久久久蜜桃| 日韩无码极品| 久久久97| 天天综合-91入口| 夜夜嗨一区| 破处bbq| 干B| 插老姨肥穴| www.操| 天天添天天干电影| 日本淫色网| 亚洲影视综合网| 97五月天| 九九九九久久久| 久久久激情| 国产伦乱91| 五月天黄色激情视频| 伊人久久大香线蕉无码| 亚洲成人久久一区二区| 91chinese在线| 人妻AV 中文字幕的| 成人av动漫在线观看| 一本一道vs波多野结衣| 日韩成人大片一区二区| 97人人模人人爽人人| 91天堂色男人的天堂| 青娱乐久久艹| 91大学精品激情戏| 91精品人妻一区二区-全集完整版免费正片国语-B02AV | 少妇天堂网络| 久久久99999久网站| 欧美婷婷久久| 色香91| 毛片99-全集电影手机免费观看完整-B029AV | 欧美色吧综合| 亚州欧美色图| 成全在线观看免费观看| 色官网在线| 再深点灬舒服灬太大了好硬好爽| 国产伊人自拍| 成人AV在线网站| 东京热av影院| 国产精品人妻一区二区| 亚洲诱惑| 亚洲中文字幕一区| 爱妃国产亚洲视频中文字幕| 國產尤物AV尤物在線觀看| 99操视频| 欧美色66| 青青草原成人| 午夜偷拍久久熟女| 99热这里只有精品9| 色九九九九久| 人妻熟妇久草在线| 97天天日| 约操熟妇| 中文字幕亚洲欧美在线不卡| 亚洲欧美啪啪| 丁香五六月啪啪| 欧美国产日韩高清在线| 欧美熟妇操操视频| 不卡视频一区蜜桃视频| 天天做日日做天天欢。| 激情露脸爱| 国产美女91| 操www| 欧美色综合影院| 欧美亚男人的天堂| 色色九区| 最近的最新的中文字幕视频| 天天看特黄的免费网站 | 亚洲五月丁香花狠狠干一区二区三区| 搡老女人老91妇女熟女| 日韩黄色av中文字幕| 婷婷丁香六月天| 亚洲天堂美臀在线| a一区二区三区乱码在线| 欧美在线视频99| 日韩精品国模| 麻花豆传媒剧国产MV出差| 九九综合久久| 欧美亚州色的图| 久久精品 六十路 熟女 欧美| 成人黑料社久久| 亚洲一区亚洲天堂| 偷拍自拍在线视频观看| 夜精品久无码| 四虎午夜影院| 高清不卡国产| 日韩性爱啪啪视频| 欧美色偷拍| 欧美天天搞| 久久综合婷婷| 欧美草草高清日韩视频| 97最新在线播放视频| 亚洲天堂日本| 亚乱色| 欧美 综合 亚洲| 曰本人妻人人澡人人夹| 99黄页网站| 蜜桃久久久久久久| 国产操伦| 五月天久久人妻| 337p大胆噜噜噜噜噜91Av| 丝袜色综合| 国产精品探花视频| 日韩欧美三级| 日韩情色视频| 国产最新小视频在线播放下载 | 伊人骚琪琪亚洲天堂网站| 国产乱伦性爱AV| 欧美日韩国产精品久久色婷婷| 国产精品久久久无码AV网站| 色亚洲欧美| 天天色粽合合合合合合合| 美欧色综合| 伊人影院中文字幕| 不卡中文字幕aⅴ在线| 日本A级视频| 91精品国产日韩欧美综合| 欧美色日本| 黄色电影观看久久9| 亚洲美腿丝袜香蕉影视欧美成人| 天天综合网站| 亚洲人体视频在线观看| 亚洲激情深爱文学小说网站| 99∨VTV| 国产免费一区2区3区| 狠狠干精品一二三四五六2022| 午夜操逼不卡| 黄色工厂这里只有精品| 欧美性区| 久久草在线综合视频| 久久日本熟妇熟色一区| 一区二区三区四区在线不卡| 色综合天天| 免费av在线播放二区| 91精品女厕偷拍视频| 97在线资源| 久久色人体| 巨爆乳一区二区爆乳区| 一二三区视频在线观看| 国产精品suv一区| 91欧美| 国产日韩欧美中文在线播放 | 天天日天天爽| 男人高清无码一区二区| 成全动漫视频观看免费下载| 精品人妻一区二区蜜桃视频| 久久精品免视看国产成人﹣蜜臀av一区. 久久精品免视看国产成人,蜜臀av一区 | 91人人| 97er欧美性| 夜夜操2028| 乱欲一区二区| 久久五月天婷婷丁香中文字幕| 学生妹天天看| 欧美少妇大量自拍视频在线观看| 欧美婷婷五月天| 亚洲国产精品9999在线观看| 白丝AV| 欧美日韩一二三| 欧美综合传媒| 欧美亚州色的图| 欧美 综合| 久碰视频| 青草av在线| 青青伊人这里只有精品| 免费人成在线观看网站品爱网| 色综91| 久9九综合在线| 综合欧美日韩在线观看| 国产亚洲精品A在线观看下载| 欧美成人精品欧美一级乱黄一区二…| 欧美一品道| 欧美综合在线91| 久久夜色一区二区| 亚洲瓯美色图| 日韩国产十八禁| 欧美香蕉视xxx| 天天看片天天爽| 欧美色偷拍 | 久久9999| 久久久久女教师免费一区| 91色s| 91亚洲欧美综合高清在线| 精品176精品2| 久久人体一区二区| 色97综合中文字幕| 风间由美日韩欧美久久| 中文字幕人妻丝袜乱一区三区| 综合九九| 人人妻人人玩人人澡人人爽| 蜜臀久久99精品久久久| 欧美激情激情xxxx欧美专区| 久久精品国产Aⅴ| 日韩一级二级三级在线不卡观看完整| 国产亚洲色停停久久99精品91| 亚洲欧美综合| 人人操我人人干| 国模不卡| 97久久久| 久久99国产综合精品女同| 精品夜夜澡人妻无码| 99青草| 青青草视频导航官网| 97天天操天天干| 久欲AV| 欧亚 另类 久| 精品无码一区二区三区| 综合欧美日韩在线观看| 大胆91| 蜜臀亚洲中文| 不卡一区二区日本视频| 欧美性爱精品一区二区| 99亚亚热| 青青操在线亚洲视频观看欧美在线| 欧美日韩国产中文超碰| 婷婷美人网| 日本熟妇自慰性高潮一区二区三区| 伊人欧美大香蕉视频| av影片在线观看不卡| 成人无遮挡毛片免费看| 五月丁香啪啪网| 大香蕉 222| 亚洲。天堂。日本在线观看| 色姑娘综合网| 8050无码八戒| 欧美日韩222| 91影视亚洲| 久久免费少妇| 国产呦精品一区二区三区下载| 大香蕉亚洲中文| 亚洲图片 激情小说| 麻豆成人影音在线| 人妻22p| 神马久久网| 欧美偷拍| 色婷婷电影网| 2019亚洲男人天堂| 久久国产免费激情视频| 亚洲欧美爆| 久久久啊啊啊| 亚洲第一无码播放立川理惠| 超碰人妻久久人妻中文97| 91亚洲最新在线| 亚洲综合另类小说色区亚洲成av人片在www | 曰韩操B| 91 丝袜在线| 超碰地址久久| 大香蕉AV在线| 午夜精品久久久久久久99| 91久久九九精品国产综合| 人妻中文在线| 天天综合网亚洲综合网| 日本天天操| 久久仑合| 精品中文字幕一区二区| 91l欧美在线| 国产精品白领在线观看| 操九九九九九九| 九九热av| 亚洲成人av色网| 中国91AV| 亚洲精品819| 欧美综合亚洲综合| 91人妻爽爽人人做人人澡| 色久桃花影院在线观看| 伊人久久国产免费观看视频| 少妇综合| 精品97精品97| 精品国产91av一区二区三区| 伊人久久大香线蕉亚洲五月天,青草青草欧美日本一区二区,欧美日产欧美日产国产 | 久久久亚洲| 色欧美天天| 亚洲国产精品无石码久久 | 黑白配性爱AV成| 福利在线黄片| 天堂综合网| 六月丁香五月婷婷| 九九综合九九综合| 99国产在线绯色一区| 97天天操| 精品176精品2| 亚洲欧美国产va在线播放频| 99久久9| 久久成人东京热人妻| 熟妇操花| 精品九九九九九九| 亚洲日本男人天堂网| 26UUU欧美日本| 夜夜狼人妻| 国产美女自拍AV| 性色国产东北露脸精品视频| 久久国产乱子伦精品免费女人| 爱爱久久| 久久婷色| 国产1024在线播放| 97精品久久久久中文字幕| 中文字幕123| 国产区在线| 任我爽视频在线观看| 蜜乳AV.COM| 亚洲欧美变态| 少妇毛片久久| 欧美日韩性爱操大逼| 99re黄| 日韩99神马视频片| 91超碰人人操| 日韩字幕一区| 97中文字幕一区| 2001天天操| 黄片com.| 久久专区| 成人AV在线网站| 真实高潮91| 日本色色色视频| 久久久久久久九九九九| 校园春色亚洲无码| 蜜色网色哟哟| 欧美十八禁在线看| 26UUU欧美激情一区二区| 超碰4A| 97久久精品国产| 看一级黄色视频| 丰满人妻一区二区三区性色| 欧美东京热青青草| 伊人四虎综合| 久久久穴999| 操碰97| 国产精品久久久久久久毛片1| 99999国产精品| 天欧美在线| 天天综合影院91| 五月丁香婷婷啪啪| 丰满少妇乱子伦精品无| AA级电影三区| 免费操逼91| 国产人妻久久精品一区二区三区| 蘋果手機免費看成人Av| 天天摸夜夜摸| 97网址www| 人妻久久久久久久久久久久久久久 | 大香蕉手机在线| 91性| 天天日美女的B| 久久综合精品一区二区三区| 日韩99999色| 69超碰综合| 五月天色综合| 天天弄天天操| 67914亚洲精品| 亚洲操操| 丁香激情五月天| 国产一区二区啪啪视频| 国产精品自在自拍视频| 日本亚洲熟女视频| 91人妻尻屄视频| 久久性爱网站| 国内毛片免费h片在线| 日韩精品 视频一区二区| 国产日韩精品人妻久久久久色欲网站 | 人人操人人操人人操人人操人人操人人人11.CM| 欧美91精品国产自产| 亚洲高清色综合| 一区二区三区看视频| JuliaAnnXXX888| 日本一线产区和二线产区伦理片| 黄色工厂这里只有精品| 免费国产视频| 无码久久国产| 亚洲欧洲综合av在线| 国产黄色影片在线观看| 亚洲AV操| 色色色欧美| 蜜臀国产AV中文字幕| 亚洲精品819| 蜜桃视频一区二区三区在线观看| 嗯嗯啊啊好疼| 加勒比性爱成人在线| 后入式福利| 东京热天堂网| 日韩欧美成人性爱在线| 国产精品午夜高潮呻吟久久av| 成视频在线观看免费看| 欧美在线官网| 人妻黑丝袜电影| 97色欧洲| 亚洲日韩人妻中文字幕一区| 萌白酱自拍视频| 免费看日产一区二区三区| 夜夜操2028| 亚洲污一污二| 1024精品在线| 久久亚洲欧美中文字幕国语| 国产粉嫩出水在线播放| 人人爽天天爽| 老鸭窝日丰县女人| 大香蕉伊人网| 日本视频在线观看污污污| 99热66| 久久综合女优| 揉揉揉夜夜| 中国操逼无码| 色综合色| 夜夜 中文视频rt| 日韩十八禁| 中文日本免费高清| 久久久久久久一级黄色打同平台| 亚洲 另类 丝袜 自拍 动漫| 亚洲a色| 国产自产自拍| 亚洲伊人久久精品狠狠在线| 99视频自拍区| 超碰在线观看av不卡| 日本三级韩三级99久久| 加勒比人妻综合| 99久久无码| 亚洲五月婷婷| 欧洲亚洲人人爽爽视频| a片偷拍视频| 天天日天天插| 99热线麻豆| 国产精品网址| 国产精品亚洲四五区在线观看| 亚洲做性| 久久一级无码精品毛片6| 少妇500双飞99| 亚洲黑人在线| 黑丝内射一区二区三区| 超碰97人人乐| 亚洲欧美日韩精品久久久一区二区 | 国产美女91| 国产精品一级片在线看| 亚洲中文字幕日产无码久久| 欧美性xxxxx狂欢| 国产 日韩 欧美 人妻 熟女 中文 69人妻精品一区二区绯色 | 熟妇无码视频三区| 日本国产欧美高清在线| 欧美熟女丝袜| 少妇3P性爱自拍| 欧美日韩精品国产91| 日韩熟女无码| 色女网日韩| 亚洲高清视频在线免费观看| 国产超碰国产97| 亚洲欧洲自拍| 亚州操操穴网| 一级一性爱免费视频| 国产精品一区人妻精品阁在线| 综合欧美色图| 首页亚洲国产高跟丝袜诱惑视频| 97操b| 日日干夜夜干| 91亚洲高清| 大香蕉伊人网WWWn0n| 亚洲天堂精品日韩电影| 蜜桃久久久久久久| 逼操网站| 天天在线91| 久热大香蕉| 97AV在线观看| 97在线欧洲| 性色生活片久久毛片婬片免费放女人一级毛片| 高潮嗯啊性感美女久久久| 草草影院最新网址| julia ann久久| 大香蕉丝袜一级片| 97日韩| 欧美无圣光在线| 国产成人无码a| 精品9999| 欧美日韩丝袜| 欧美日韩啪啪电影| 舔舔啊| 亚洲黑丝在线| 日韩一区二区精彩视频| 国产女人9999| 狠狠五月天| 中文字幕黄片在线| 男人天堂网手机版婷婷| 五月色综合| 青青青国产手线观看视频2| 亚洲和欧美裸体美女双飞视频| 在线可观看的黄色网址| 天天操天天舔| 天美欧美国产| 久久免费精彩视频| 欧美自拍偷拍综合图片| 91天天爽| 日本999精品视频| 欧美日韩中文亚洲v在线综合| 啊啊啊啊啊啊在线观看| 裸体1区| 九九成人| 丝袜剧情| 日本成a人v网站在线观看| av久日| 亚洲骚女一区二区三区| 蜜乳AV网址| 色吧5亚洲| 超碰97人人乐| 久久久久久中文版| 午夜天堂精品久久久久91| 特级特黄一级毛片免费| 日韩综合97p| 超碰免费欧美7| 国产13区| www.色婷婷| 亚洲日韩美女中文字幕乱| 欧美精品宗合| 欧洲亚洲人妻无码高清久久三区四区| 日本日日色视频| 九九色色| 在线观看综合精品亚洲| 亚洲密乳AV| 青草成人免费视频一com| 欲色啪| 亚洲涩涩| 国产成自自拍在线观看| 超碰久久中文| 热久久这里只有精品| 黑人嘿嘿嘿超爽免费视频| 欧美性爱日韩高清| 日韩亚洲欧美中文字幕| julia国产在线| 插B在线观看| 亚洲综合骚逼| 牛牛久久国产精品视频一二三 | av网站免费线看| 久久激情婷婷| 日本久久超碰| 伊人91| 精品人妻一区二区三区免费视频| 91操人| 色拍偷亚洲| 中文字幕AV片| 大肉棒导航| 日本99一区二区| 欧美 日韩 国产传媒| 黄色大片一区二区密桃丝袜| 亚洲男人天堂2019| 国产亚洲人妻综合日韩 久久| 看一级黄色视频| 国产自偷自拍一区| 99热婷婷| 国模一区二区三区| 日韩女优中文字幕| 少妇与黑人高潮在线| 欧亚乱色熟一区二区三四区| 青青青操| 99re95| 欧美夜色| 欧洲亚洲人人爽爽视频| 懂色av中文字幕一区二区三区天美| 97爱b| 亚洲极品| 欧美se综合| 综合网 欧美| 色视频蜜乳| WWW啪啪的com| 中日韩欧美精品无码AⅤ一区二区| 93人人操人人| 99ri在线视频| 色女网日韩| 97精品国产手机| 九草九九九| 伊人九九九| 草草草视频在线免费看| 激情抓乳插进去啪啪啪日韩| 久久无码电影| 女优视频第10页| 国产偷仑| 青青草在线视频美女| 欧美色图亚洲色| 四虎午夜影院| 欧美顶级黄片AAAAA在线免费看| 婷婷五月天影院| 少妇与黑人高潮在线| 欧美激情亚洲情色| 超碰97中文| 黄色AAAAA欧美| 蜜臀少妇一区二区| 夜夜综合| 日本久久超碰| 黄色区免费观看中文字幕| 9久热| 久日91在线| 熟妇人妻丰满久久久久久久无码| 富女玩鸭子一级毛片| 亚洲砖码砖专无区2023| 人妻夜夜爽天天爽麻豆三区网站 | 91亚州欧美| 少妇贴图| 日韩卡一卡二卡三在线| 久久久久13| 国产热av| 操逼视频色| 天天色综合图片| 亚洲日韩乱码中文无码蜜桃臀网站| 99re黄 | 成人情色综合网| 超碰97人妻免费在线| 人人色人人操在线| 精品人妻一区二区三区视频| 国产精品扒开腿做爽爽爽视频| 亚洲成人久久一区二区| 亚洲综合有玛| 久久少妇| 五月丁香六月婷| 亚洲图片 激情小说| 超碰色综合| 九九色色| 精品女同一区二区三区| 成人亚欧免费视频| 婷婷情色五月天| 搡老女人老91妇女老熟女| 一区三区啪啪| 亚洲色图自拍| 99re国产精品视频| 午夜性| 亚洲av噜噜噜噜噜噜| 亚洲综合激情五月久久| 久9综合在线| 把腿张开老子CAO烂你| 亚洲情色在线| 眼镜人妻101.com| 少妇诱惑视频| 婷婷操视频| 午夜呻吟欧美| 婷婷婷婷婷婷久久久久| 午夜天堂精品久久久久91| 成年在线视频日本亚洲在线视频区精品江靖宇公司| 密乳无码| 国产和美国毛片| 亚洲无码免费看| 性爱欧美五月| 国产无马视频| 91无摭挡| 免费A V在线播放| 男人的天堂日韩| 囯产操逼片| 狠狠躁日日躁夜夜躁A| www.91理论| 尤物视频偷拍免费| 青娱乐日韩无码| 风韵犹存大大大大香蕉| 九九av| 欧美色女人| 嗯阿好爽好紧| 伦激情人妻另类人妻| 天天摸夜夜操视频| 国产精品久久久无码AV网站| 夜夜夜夜爽| 欧美日韩99| 中文乱码字幕观看| 久久深夜无码| 国产 日韩 欧美 中文 另类,国产 欧美 另类 制服 变态,高清 日韩 欧美 中文,高 | 操B久久| www.久久最新地址| 男人天堂无码| 婷婷日韩一区二区三区中文字幕在线| 久久久九九九| 老熟妇一区二区三区啪啪| 国产精品久久久久久 百度| 欧美色图自拍| 日本高清电影欧美色图| 99久久亚洲精品无码毛片潘甜甜 | 免费啪啪一级视频| 殴美性天天| 中文字幕免费观看| 亚洲精品a人片在线观看视| 好涩综合| 欧美色日本| 伊人久久婷婷| 中文字幕日韩专区精品系列 | 亚洲欧洲自拍图片专区满春格| 小草av不卡亚洲二区| AV综合中文字幕干| 日韩操啪| 狠狠97| 一区中文字幕二区日韩| A片 AV一级在线播放观看免费| 国产精品播放| 欧美论理片| 日本有码影片下载| 国产精品无码av| 超碰97 线线 在现| 欧美一级专区免费大片 | 欧美成人免费在线观看| 美女91av| 欧美色图亚洲色图成人在在线| 亚洲第一黄色av网站| 五月天亚洲色图| 国产一区二区在线播放,久久亚洲精品中文字幕第一区,亚洲精品在线中文字幕视频 | 青木玲在线不卡| 中文字幕二区日韩天堂| AV不卡在线| av亚欧| 大逼色网站| 日韩一级二级三级免费看完整版国语版| 激情五月激情综合网| 十八禁av无码免费网站APP| 天天久久| 亚洲色天堂九9| 啊啊啊好大好湿| 色狠狠综合噜一二三区| 99久久综合| 最近2019中文字幕国语免费版| a片自拍直播视频| 午夜欧美精品久久久| 久久大精品乱码视频人妻熟女| 国产蜜臀精品一区免费尤物| 免费A V在线| 国产乱码精品一区二区三区四川| 亚洲国产一级黄色视频| 91宗合网| 亚洲中文丝袜美腿诱惑字幕| 国产成人精品午夜福利| 九九热这里只有在线精品视 伊人草 成人菠萝蜜视频在线观看 | 青青草国产盗摄一二三区| 超碰79人人乐| 色婷婷成人| 亚洲精品成人激情在线| 黑人操一区二区| 天天色天天干天天爱| 97超碰磁| 偷拍 欧美 日韩| 亚洲九九九九| 日韩97| 国产色图乱伦| 3PAV乱伦视频| 国产一级内射高清视频| 啊v在线观看视频| 欧美一级二级三级| 人妻丝袜一区二区三区在线| 骚鸭AV| 久久日韩肥臀| 特污精品女优骚货黄色视频在线免费观看| 青青草五月份天| 欧美亚洲韩国视频十五区| 综合天天。| 蜜臀va69| 春色综合网| 日本一区二区三区四区五区六区七区八区九区| 97操碰| 美女9118禁| 亚洲天堂欧美| 熟女激情综合网| 日韩黄色av中文字幕| 亚洲好看强奸乱伦| 老司机老司机午夜影院| 亚洲图片欧洲图片aⅴ| 丰满少妇乱子伦精品无| 性爱1区| 啊啊啊啊嗯嗯嗯用力好爽| 97人肏| AV天堂男人的天堂| 久热久操| 亚洲第一男人天堂| 欧美日韩久久精品爱爱| 久久大黄片| 为用户提供免费看黄网址在线观看| 亚洲天堂中文字| 国产成人精品亚洲日本| 一区二区三区在线资源| 99999精品成人| 亚洲97p| 蜜臀久久99精品久久久久久成人小说 | 色婷婷小说| 97蜜桃综合| 校园春色中文字幕AV| 精品人妻一区二区三区蜜桃视频| 欧美劲爆第一页| 国产综合在线视频网站| 五月天婷精品激情| 精品国产乱码久久久久久影片| 91亚洲影院综合| 成人情色综合网| 丁香色狠狠色综合久久小说| 亚洲第一精品在线视频| 色婷婷电影网| 玖玖爱一区在线| 91热| 国产乱伦亚洲| 亚洲操操操| 天美欧美国产| 玖玖综合网| 中文字幕交换人妻| 女人的久久久| 欧美日韩美女精品久草一区二区三区| 亚洲欧美伦综合| 亚欧视频在线| 国产黄a三级三级三级av在线看| 天天色怡春院| 操国产高清| 欧美精品1区2区3区| 国内精品久久国产,www香蕉久久五月丁香,亚洲欧美日韩精品永久在线,日本精品一 | 超清福利精品视频在线| 国模吧 一区二区三区| 自拍丝袜美腿人妻| 台湾佬大香蕉| 盗摄女人妻在线| 91大神电影天堂| 国产后入式在线观看| www.久久制服糖| 人妻啊啊人妻啊啊| 男人天堂久久精品不卡| 精品国产Av无码久久久亚洲| 91碰碰| 亚洲午夜蜜臀| 三级特黄60分钟播放| 久久婷婷一区二| 小电影欧美91| 思思热在线cao| 久久嫩草国产成人一区| 大香蕉99999| 国产一区二区视频在线播放| 久久一二三四五六七八九区区| 欧美懂色综合网| 99re久久| 91操熟妇| 国产精品久久久久久片| 九九热视频这里只有精品| 91人妻熟女| 色婷婷成人| 9久9久| 久精品无码av一区二免费国产在线观看| 久久亚洲天天做| 欧美影院一区二区三区| 性爱动态120秒| 亚洲人妻五月丁香婷婷| 99ri精品| 91蜜臀人妻中文字幕在线| 大香网站| 国产91专区| 人人操人人uiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii | 麻豆60秒| 久久久久久97| 91网站18在线观看| 91美女视频在线观看| 日本大片日本一区二区免费高清| av2014 日韩在线中文字幕| 牛牛aV| 四虎影视国产精品| 亚洲各类熟们中文字幕| 91中出在线| 99在线精品观看99| 日韩欧美女求操每天更新| 99热官网| 日本一道在线播放高清| 肥臀熟女福利视频一区二区| 欧美夜夜草视频| 亚洲美欧999| 中文字幕精品一区欧美| 九九九九九九九九九五码| 中国zzijzzijzzwww精品| 青青操视频在线| 亚洲Av无码成人精品国产| 成人九九| 久久黄黄| 色婷婷六月丁香七月婷婷| 97精品97| JULIA一区二区三区在线播放| 香港久久久| 久久精品视-一级做a爰片性色毛片16美国-中国女与老外在线精品 | 日日日啊啊啊| 被男人添B超爽视频| 啊啊啊久久久视频| 国产精品秘 福利姬在线观看| 欧美天天搞| 亚洲乱色视频一区、二区在线| 亚洲精品三区在线观看| 综合网亚洲1| 殴美牲| 亚洲欧美综合区自拍另类| 超碰视97中文| 91狠| 欧美成人AⅤ大片在线观看| 久久日韩肥臀| 亚洲AO在线| 国产一区二区视频在线播放| 国内外内射高清视频| 日韩欧美水蜜桃人妻| 国产亚洲在线观看| 久久久久亚洲熟妇熟女| 日韩色图 一区二区| 久久久久久久久久久六六| av天堂精品久久| 欧美96在线|欧| 九九英色视频| 柠檬AV导航| 小日子操bb在线看| 久久这里只| 激情视频一二三| 狼天天狼天天大香蕉| 国产久久av| 日产操逼| 日本幼女18+| 9999亚洲电影| 天美传媒国产原创中文字幕亚洲欧美另类| 日韩精品在线观看观看| 好爽视频在线观看视频 | 一区二区三区免费岛国片| 97干97色| 99超碰网| 亚洲综合一| 美女97超碰| 天天综合91在线| 国产成人bd在线观看| 91福利网在线观看| 激情小说激情视频| 91n免费处女| 97超久碰| 亚洲天堂女优在线| 色情综合网| 一级久久性爱视频| 国内偷自视频区视频综合| 超碰97护士| 日韩精品亚洲一二三| 97就爱干| 精品999日本| 四季AV综合网址| 欧洲天天在线| 婷婷大香蕉| 免费黄色视频网址| 亚洲图片欧洲图片aⅴ| 狠狠操官网| 岛国黄片网站| 操一操摸一摸| 超碰97人妻在线| 日韩97在线| 色约约一区=区三区| 色777999综合| 久湿久久| 99日免费视频中文字幕| 黄色不卡视频| 樱花草社区www中国| 欧美爆操91| 亚洲欧美日韩有码| 嗯~啊~快点 死我视频| 久久亚洲影院一区二区| 丁香激情网| 国产11页| 91男女啊啊啊| 丝袜夫妻自拍| 按摩中文字幕| 一区=区三区视频| 欧美三级免费伊人| 老师充足的奶水小说| 欧美熟妇精品黑人巨大一二三区| 97干在线看| 欧美色66| 超碰538| 欧美激情色婷婷花野真衣一区二区| 国产成人无码啪| 两女互慰AV高潮喷水在线观看| 91观看 国产白丝| 91Chinese在线| 欧美操人| 激激五月| 天美一二三在线观看Av| 大香蕉在线视频重口味毛片在线| 抽插爽| 亚洲91大片| 综合亚洲网| 国产精品女aA片爽爽视频|