国产成人欧美一区二区三区vr_久久国产精品人人爽人人爽_国产精品永久免费播放_肉欲啪啪a∨无码精品一区二区_国产超短裙jk丝袜在线_亚洲AV片高清资源在线观看_国模无码一区二区三区久久_国产成年人未进视频_中文字幕无码精品夜_一区二区三区在线视频免费看_亚洲成AV人片在线观看网址_日本激情视频高清综合久久_亚洲午夜视频福利_国内大量揄拍人妻精品視_久久国产精品福利二区三区

ARTICLE DETAIL

資訊詳情

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

XSD到Java:用XJC代碼生成器高效解析XML Schema實(shí)戰(zhàn)指南

XSD到Java:用XJC代碼生成器高效解析XML Schema實(shí)戰(zhàn)指南 前陣子對接一個外部供應(yīng)商接口對方丟了個 XSD-7 數(shù)據(jù)契約文檔過來沒有現(xiàn)成的 SDK只給了一份 XML Schema 規(guī)范和樣例報(bào)文。當(dāng)時項(xiàng)目時間很緊報(bào)文結(jié)構(gòu)特別復(fù)雜嵌套十幾個層級還有一堆枚舉、擴(kuò)展類型和 choice 分支。如果按老套路手寫 Java 映射類光對字段就得耗掉小一周而且容易出現(xiàn)類型對不上、枚舉漏掉值這種低級錯誤。后來直接上了 XJC 代碼生成器JAXB 編譯器把 XSD-7 文檔喂進(jìn)去一套 Java Bean 全部自動生成幾分鐘就把這個硬骨頭啃下來了。如果你也是做 Java 服務(wù)端對接、處理 XML 報(bào)文、或者被各種 XSD 文檔折磨過的開發(fā)者這篇文章應(yīng)該能幫你少走不少彎路。我會把 XSD 如何映射成 Java 類的底層邏輯、XJC 命令行的完整使用姿勢、以及我實(shí)戰(zhàn)中踩過的坑和對應(yīng)的外部綁定文件寫法都整理出來算是一份可以直接拿去用的實(shí)操筆記。這篇文章基于我自己在實(shí)際項(xiàng)目里使用 XJC 的經(jīng)驗(yàn)結(jié)合一份名為 XSD-7 的 XML Schema 契約文檔逐步展開。所有示例均為虛構(gòu)數(shù)據(jù)但處理思路和命令用法都是實(shí)打?qū)嵉摹?. XSD-7 這份數(shù)據(jù)契約到底在描述什么先別急著敲命令我建議任何人拿到 XSD 文件的第一件事都不是生成代碼而是先把這份 Schema 從頭到尾讀一遍。以 XSD-7 為例這其實(shí)是一份交易報(bào)文級的 XML Schema 文檔定義了多個全局元素和復(fù)雜類型。XML SchemaXSD本身就是用來描述 XML 文檔結(jié)構(gòu)的“合同”它會告訴你哪些元素存在、元素之間的嵌套關(guān)系、數(shù)據(jù)類型、取值范圍、是否必填、出現(xiàn)次數(shù)等等。XJC 所做的就是把這份“合同”用 Java 語言重新表達(dá)一遍生成一套對應(yīng)的 Java 類核心就是把 XML 世界里的復(fù)雜類型映射成 Java 里的類把元素和屬性映射成字段把簡單類型映射成 String、Integer 之類的 Java 類型然后通過 JAXB 注解把這些映射關(guān)系記錄下來。1.1 讀懂 XSD-7 里最常見的三種類型聲明XSD-7 這種文檔大量出現(xiàn)的無非是這幾種聲明xs:element、xs:complexType、xs:simpleType。xs:element就是定義某個 XML 元素的名稱和類型xs:complexType代表一個結(jié)構(gòu)體內(nèi)部可以有子元素或?qū)傩詘s:simpleType則是一個約束了取值范圍的簡單類型通常配合xs:restriction使用比如限制成一個枚舉。比如 XSD-7 里經(jīng)常能看到類似下面這種片段xs:complexType nameOrderInfo xs:sequence xs:element nameorderId typexs:string/ xs:element nameamount typexs:decimal/ xs:element namecurrency typeCurrencyCode/ /xs:sequence xs:attribute nameversion typexs:string userequired/ /xs:complexType這個OrderInfo復(fù)雜類型翻譯成人話就是一個訂單信息結(jié)構(gòu)體里面依次有訂單號字符串、金額小數(shù)、幣種枚舉并且掛著 一個必填的 version 屬性。XJC 拿到這段定義之后會生成一個名為OrderInfo的 Java 類類里有orderId、amount、currency三個字段以及一個version屬性字段全部用XmlElement、XmlAttribute注解標(biāo)注清楚。1.2 別忽略 targetNamespace 和 import/includeXSD-7 這種正式契約文檔幾乎一定會有targetNamespace這決定了生成 Java 類的包名級 XML 命名空間映射。比如聲明了targetNamespacehttp://example.com/trade/order默認(rèn)情況下 XJC 會根據(jù)這個命名空間生成一個包名。還有xs:include和xs:import這種跨文件引用——XSD-7 很可能是由主文件加若干子 Schema 組成的主文件 include 了其他文件里的公共類型。處理這種多文件結(jié)構(gòu)時不要用單個 xjc 命令去裸編譯而是要把整個文件集合放在同一個目錄、直接用主文件作為入口參數(shù)否則會出現(xiàn)找不到類型的報(bào)錯。拿到一份 XSD先花 20 分鐘把頂層設(shè)計(jì)、命名空間、include 關(guān)系理清楚這比上來就跑命令省事得多。因?yàn)?XJC 報(bào)錯的很多問題本質(zhì)上都是文檔結(jié)構(gòu)沒理清導(dǎo)致的。2. 從 XSD 到 Java 的映射算法XJC 編譯器的底層工作邏輯很多人用過 XJC但它內(nèi)部到底按什么規(guī)則把 XSD 轉(zhuǎn)換成 Java其實(shí)說不清楚。這塊搞明白了后面很多坑你都能提前避開因?yàn)閹缀跛械摹盀槭裁瓷沙鰜硎沁@樣的類”都能在這個映射邏輯里找到答案。2.1 復(fù)雜類型和元素類與字段的對應(yīng)規(guī)則在 XJC 的世界里一個xs:complexType大多數(shù)情況下會被映射成一個 Java 類。這里的“大多數(shù)情況”是有講究的如果這個復(fù)雜類型是有name的那么直接生成一個以該名字命名的類如果它是嵌在某個xs:element內(nèi)部、沒有顯式名字的匿名復(fù)雜類型XJC 會依據(jù)元素名派生出一個類名。比如xs:element namecustomerxs:complexType...XJC 通常會生成一個叫Customer的類。復(fù)雜類型內(nèi)部的xs:sequence、xs:all、xs:choice里的每個子元素都會變成類里的一個字段。xs:sequence是順序敏感的子元素序列映射成 Java 字段時按 Schema 里聲明順序排好xs:all是一組無序但每個出現(xiàn)一次的子元素映射成一個普通字段集合xs:choice是幾個分支中只能出現(xiàn)其中一個XJC 會生成一個帶XmlElements注解的字段列表Java 類型是ListObject或者泛型化的JAXBElement?。minOccurs和maxOccurs也直接決定字段類型——maxOccursunbounded或大于 1 時字段是 ListminOccurs0時會生成XmlElement(required false)并允許空值。2.2 簡單類型枚舉、約束和 Java 基礎(chǔ)類型的映射xs:simpleType配合xs:restriction是 XSD-7 里最常見的數(shù)據(jù)校驗(yàn)手段也是最容易被忽視的部分。比如xs:simpleType nameCurrencyCode xs:restriction basexs:string xs:enumeration valueCNY/ xs:enumeration valueUSD/ xs:enumeration valueEUR/ /xs:restriction /xs:simpleTypeXJC 默認(rèn)會把這種類型生成成一個 Java 枚舉類CurrencyCode枚舉常量就是 CNY、USD、EUR。這里有一個關(guān)鍵點(diǎn)默認(rèn)生成的枚舉值名稱來自 XSD 里的value屬性如果value里有空格、連字符或者數(shù)字開頭比如USD-1、EUR(2024)XJC 會做一次名稱清理但往往不太好看而且可能會有兩個不同取值被轉(zhuǎn)成同一個合法的 Java 標(biāo)識符直接導(dǎo)致編譯失敗。對于普通的xs:restriction比如限制長度、限制正則但沒有 enumerationXJC 不會生成特殊類型而是把它映射為基于base類型的 Java 基礎(chǔ)類型。簡單類型映射規(guī)則我用表格總結(jié)一下XSD 類型Java 類型默認(rèn)備注xs:stringString最常見無歧義xs:integerjava.math.BigInteger注意不是 int/longxs:intint受限于 32 位整數(shù)xs:longlong64 位xs:decimaljava.math.BigDecimal金額類必用xs:booleanboolean默認(rèn) false容器對象時用 Booleanxs:dateTimejavax.xml.datatype.XMLGregorianCalendar默認(rèn)映射后文詳談xs:datejavax.xml.datatype.XMLGregorianCalendar默認(rèn)映射不適合直接序列化xs:base64Binarybyte[]字節(jié)數(shù)組xs:anyTypeObject最泛用的類型xs:integer默認(rèn)映射成 BigInteger 是很多人第一次用會驚訝的地方因?yàn)檫@在 Java 里有點(diǎn)重但為了兼容 XML 里的任意整數(shù)精度JAXB 把它設(shè)計(jì)成 BigInteger。如果你確信業(yè)務(wù)上精度夠用可以在 binding 文件里做定制后面會專門寫。2.3 namespace 與包名生成的默認(rèn)策略XSD-7 文檔里的targetNamespace是包名生成的核心依據(jù)。比如http://example.com/trade/order這種 URIXJC 會根據(jù)逆域名規(guī)則生成包名通常是com.example.trade.order之類。但如果你的命名空間寫得不規(guī)范比如帶上了版本號http://example.com/order/v1生成的包名就會包含v1再比如命名空間里包含不是標(biāo)準(zhǔn)域名的局部生成結(jié)果可能是一長串下劃線橫線的奇怪包名。XJC 官方設(shè)計(jì)是把 URI 拆解并反轉(zhuǎn)但結(jié)果往往不符合 Java 包命名直覺。所以我的建議是除非迫不得已生成代碼時永遠(yuǎn)用-p參數(shù)顯式指定目標(biāo)包名不要讓 XJC 從命名空間推導(dǎo)。這樣能完全避免包名失控的問題。比如xjc -p dev.example.xsd7.model xsd-7.xsd這個-p參數(shù)就是用來覆蓋自動包名推導(dǎo)的。我每次對接外部 Schema 都會把它設(shè)成項(xiàng)目內(nèi)獨(dú)立的 model 包方便后期整體管理。3. 命令行生成實(shí)戰(zhàn)把 XSD-7 編譯成 Java 類的完整操作前面的理論部分搞明白之后進(jìn)入實(shí)操環(huán)節(jié)。XJC 這個命令說簡單也簡單就是一個命令行工具說復(fù)雜也復(fù)雜因?yàn)樗泻芏鄥?shù)和隱藏行為。我以一份本地的 xsd-7.xsd 主文件為例展示我從拿到文件到生成代碼落地的全過程。3.1 環(huán)境準(zhǔn)備JDK 版本和 JAXB 依賴的取舍先看一個大前提JDK 8 自帶了 JAXB 和 XJC直接在命令行敲xjc就能用編出來的代碼也是基于javax.xml.bind注解的。但是如果你用的是 JDK 11 或更高版本Oracle 已經(jīng)從標(biāo)準(zhǔn) JDK 里移除了 JAXB 模塊命令行里沒有現(xiàn)成的 xjc 可用得單獨(dú)引入依賴或者下載插件。JDK 17 以后尤其明顯。我們項(xiàng)目里用的是 JDK 17所以我處理 XSD-7 時直接在 Maven 里集成了org.jvnet.jaxb2:maven-jaxb2-plugin插件這個插件會在構(gòu)建階段自動調(diào)用 XJC 生成代碼不需要單獨(dú)裝工具。如果你只是想快速生成一次代碼看看效果也可以下載獨(dú)立的 JAXB 工具包但我更推薦直接走構(gòu)建插件因?yàn)樯纱a和構(gòu)建流程可以保持同步Schema 一變就重新生成。依賴配置大概長這樣按當(dāng)前主流 JAXB 版本dependency groupIdorg.glassfish.jaxb/groupId artifactIdjaxb-runtime/artifactId version2.3.8/version /dependency如果是新版 Jakarta namespace 的項(xiàng)目需要改用jakarta.xml.bind的坐標(biāo)這里不展開但你必須意識到 JAXB 已經(jīng)被 Java EE 轉(zhuǎn)移到 Jakarta EE 了不同項(xiàng)目的包名前綴不同。3.2 用命令行 xjc 完成第一次生成假設(shè)我在項(xiàng)目的xsd/目錄下放了三個文件xsd-7.xsd、xsd-7-common.xsd、xsd-7-enum.xsd主文件 include 了后兩個。最直接的命令是xjc -d ./generated -p dev.example.xsd7.model xsd/xsd-7.xsd參數(shù)解釋-d指定生成 Java 文件的輸出目錄-p指定生成類的包名末尾緊跟主 Schema 文件路徑執(zhí)行完成之后generated/dev/example/xsd7/model/下會出現(xiàn)一堆.java文件。每個復(fù)雜類型一個文件每個枚舉一個文件可能還包含ObjectFactory.java和package-info.java。ObjectFactory是 JAXB 上下文創(chuàng)建時用于創(chuàng)建各類實(shí)例的工廠類package-info.java里則攜帶了命名空間信息包含XmlSchema注解。第一次跑成功之后先把生成的類放到 IDE 里編譯一下看看有沒有編譯錯誤。這里我要特別提一個最常見的問題多個文件互相引用時類名沖突。比如xsd-7-common.xsd里定義了一個叫Status的復(fù)雜類型xsd-7.xsd里也定義了一個叫Status的復(fù)雜類型而且兩個類型語義不同。這種情況下 XJC 在一開始就會報(bào)“類沖突”之類的錯誤你需要先在 Schema 層面解決命名沖突或者用 binding 文件給其中一個重命名否則永遠(yuǎn)生成不了代碼。我會在下一章節(jié)詳細(xì)寫這些坑的排查思路。3.3 Maven 插件集成構(gòu)建期自動生成代碼命令行生成一次可以但 Schema 一旦更新手動重新生成代碼并提交到倉庫里很容易產(chǎn)生大 diff也容易忘記同步。我更推薦把 XSD-7 的代碼生成放到 Maven 構(gòu)建生命周期里配置如下plugin groupIdorg.jvnet.jaxb2/groupId artifactIdmaven-jaxb2-plugin/artifactId version0.14.0/version executions execution goals goalgenerate/goal /goals /execution /executions configuration schemaDirectoryxsd/schemaDirectory schemaIncludes includexsd-7.xsd/include /schemaIncludes generatePackagedev.example.xsd7.model/generatePackage generateDirectory${project.build.directory}/generated-sources/jaxb/generateDirectory /configuration /plugin這個配置里最關(guān)鍵的是generateDirectory放在target/generated-sources/jaxb下這樣的話生成的代碼不會進(jìn) Git 倉庫每次構(gòu)建都是全新的。同時 IDE 會自動把target/generated-sources加進(jìn) classpath開發(fā)時調(diào)用生成的類不會有任何區(qū)別。這種做法最大的好處是代碼生成和 Schema 源文件強(qiáng)一致Schema 改了重新編譯就自動更新不用手動維護(hù)一坨生成出來的 Java 代碼。個人經(jīng)驗(yàn)是讓xsd/目錄納入版本控制生成目錄不納入版本控制。這樣別人拉下代碼也能直接編譯。如果遇到需在 CI 構(gòu)建機(jī)上跑的情況插件會自動下載 XJC 依賴無需額外安裝。4. 第一批生成代碼里的坑命名沖突、非法標(biāo)識符與編碼問題每次生成完代碼我?guī)缀醵家幚硪慌鷨栴}。這些問題不是 XJC 的 bug而是 XML Schema 世界的自然規(guī)則和 Java 語言規(guī)則之間的摩擦。如果你提前知道它們排查起來會快很多。我挑幾個高概率遇到的講一講。4.1 XML 名稱與 Java 關(guān)鍵字的碰撞XSD-7 里出現(xiàn)過這種情況某個元素叫xs:element nameclass ...比如字段名就叫class。這在 XML 里完全合法但映射成 Java 字段時就成了關(guān)鍵字直接編譯不過。XJC 遇到這種情況一般會做某種轉(zhuǎn)義有時會自動生成一個類似classValue或_class的字段名但有時又不會結(jié)果就是編譯錯誤。真正的解決方式是在綁定文件里自定義屬性名。類似地還有abstract、interface、native等。我遇到過最離譜的一個是元素名叫package生成字段變成了_package——這還是 XJC 默認(rèn)給加了下劃線前綴的結(jié)果。所以生成完代碼之后第一件事就是在 IDE 里全局編譯把所有語法錯誤揪出來。4.2 兩個Status類的生死沖突多 Schema 文件項(xiàng)目中命名沖突概率比我預(yù)想的高很多。XSD-7 主文件里定義了一個Status復(fù)雜類型某個被 include 的子 Schema 里又定義了一個Status簡單類型這就是典型的“同名不同類型”。XJC 在遇到這兩個類型時如果恰好被分配到了同一個 Java 包就會產(chǎn)生同名類沖突命令執(zhí)行到一半就報(bào)錯。這種情況我建議優(yōu)先在 XML Schema 層面解決也就是讓 Schema 提供方改名。但如果外部系統(tǒng)不規(guī)范、沒法推動那就只能在 binding 文件里對其中一個類型額外指定類名。綁定文件的內(nèi)容類似jaxb:bindings version1.0 xmlns:jaxbhttp://java.sun.com/xml/ns/jaxb xmlns:xshttp://www.w3.org/2001/XMLSchema jaxb:bindings schemaLocationxsd-7.xsd node/xs:schema jaxb:bindings nodexs:complexType[nameStatus] jaxb:class nameOrderStatus/ /jaxb:bindings /jaxb:bindings /jaxb:bindings這段綁定的意思是在xsd-7.xsd里找到名為Status的復(fù)雜類型把它生成的 Java 類名改為OrderStatus。這樣兩個 Status 就能共存了。4.3 枚舉值里的空格、連字符和數(shù)字開頭枚舉值的坑我在前面提到過。XSD-7 的幣種枚舉還算常規(guī)但有一段報(bào)文里的枚舉值居然是HIGH-RISK、LOW_VALUE、3RD_PARTY這種風(fēng)格。XJC 默認(rèn)生成枚舉常量時會做非法字符替換比如HIGH-RISK會變成HIGH_RISK3RD_PARTY會變成_3RD_PARTY。單個看沒問題但萬一你有兩個枚舉值分別叫HIGH-RISK和HIGH_RISK一個是連字符一個是下劃線XJC 替換之后兩個都指向HIGH_RISK就沖突了。我的處理辦法是在綁定文件里給每個枚舉值顯式指定成員名用typesafeEnumMemberName或者typesafeEnumMember。到了這一步你也會發(fā)現(xiàn)外部系統(tǒng)發(fā)的枚舉里“同含義不同寫法”的情況特別多手動指定反而是最穩(wěn)妥的。4.4 編碼問題漢化注釋和亂碼XSD-7 里如果帶有中文注釋、中文描述性文檔XJC 默認(rèn)生成的 Java 文件里的注釋通常能保留但前提是文件編碼一致。我遇到過 XSD 文件里聲明?xml version1.0 encodingUTF-8?但文件本身是 GBK 編碼的情況導(dǎo)致生成的注釋全是亂碼。更常見的坑是 Windows 平臺下命令行 xjc 默認(rèn)輸出編碼不匹配Java 源碼里出現(xiàn)奇怪的字符。我的建議所有 Schema 文件統(tǒng)一轉(zhuǎn)成 UTF-8 編碼命令行上加-encoding UTF-8參數(shù)Maven 插件側(cè)也要配置項(xiàng)目編碼為 UTF-8。這塊是純環(huán)境問題但真遇到了會浪費(fèi)不少時間。xjc -d ./generated -p dev.example.xsd7.model -encoding UTF-8 xsd/xsd-7.xsd5. 外部綁定文件實(shí)戰(zhàn)讓 XJC 按你的規(guī)范生成代碼XJC 默認(rèn)生成的代碼能滿足“能用”的要求但往往不滿足“好用”的要求。比如日期類型映射成XMLGregorianCalendar就非常難用序列化 JSON 時也很別扭。好在 JAXB 提供了強(qiáng)大的外部綁定機(jī)制你可以寫一個.xjb文件來覆蓋各種默認(rèn)映射讓代碼更符合項(xiàng)目的實(shí)際需要。5.1 日期時間類型從 XMLGregorianCalendar 換到 LocalDate/LocalDateTimeXSD 里的xs:date、xs:dateTime默認(rèn)映射成javax.xml.datatype.XMLGregorianCalendar。這個類本身沒問題但日常開發(fā)用起來極其繁瑣和 JSON 序列化、數(shù)據(jù)庫操作都不搭。我強(qiáng)烈建議通過javaType定制把日期映射為 Java 8 時間類型。實(shí)現(xiàn)方式有兩種一種是在jaxb:globalBindings里直接定制全局類型映射另一種是寫一個XmlAdapter并配合XmlJavaTypeAdapter注解。全局綁定的例子jaxb:bindings version1.0 xmlns:jaxbhttp://java.sun.com/xml/ns/jaxb xmlns:xshttp://www.w3.org/2001/XMLSchema jaxb:globalBindings jaxb:javaType namejava.time.LocalDate xmlTypexs:date parseMethodcom.example.adapter.JaxbDateAdapter.unmarshal printMethodcom.example.adapter.JaxbDateAdapter.marshal/ /jaxb:globalBindings /jaxb:bindings這里parseMethod和printMethod指向一個自定義類里的兩個靜態(tài)方法。對應(yīng)適配器類類似這樣public class JaxbDateAdapter { public static LocalDate unmarshal(String v) { return v null ? null : LocalDate.parse(v); } public static String marshal(LocalDate v) { return v null ? null : v.toString(); } }這樣從 XML 反序列化時XJC 就會自動調(diào)用unmarshal把字符串轉(zhuǎn)成LocalDate序列化時調(diào)用marshal輸出標(biāo)準(zhǔn)字符串。改造過后生成的 Java 類字段類型就是LocalDate了讀寫和業(yè)務(wù)層面都干凈很多。5.2 金額類型確保 decimal 映射到 BigDecimal 而不是 doubleXSD-7 里金額字段用的都是xs:decimal默認(rèn)映射是BigDecimal這個沒問題。但常見的問題是自定義類型里寫了basexs:double或basexs:float這會導(dǎo)致金額字段變成double精度上很容易出問題。外部系統(tǒng)如果這么設(shè)計(jì)我一般會在 binding 文件里把該簡單類型強(qiáng)制改掉jaxb:bindings schemaLocationxsd-7.xsd node/xs:schema jaxb:bindings nodexs:simpleType[nameMoneyType] jaxb:javaType namejava.math.BigDecimal xmlTypexs:decimal parseMethodcom.example.adapter.DecimalAdapter.unmarshal printMethodcom.example.adapter.DecimalAdapter.marshal/ /jaxb:bindings /jaxb:bindings雖然xs:decimal默認(rèn)就是 BigDecimal但顯式聲明一次能防止某些插件版本或者 XSD 變體把它降級也能給人提示這個字段是金額不是普通小數(shù)。5.3 重命名類和字段的通用姿勢前面講了用jaxb:class name.../修改類名。對于字段名可以在對應(yīng)元素節(jié)點(diǎn)上用jaxb:property name.../修改jaxb:bindings schemaLocationxsd-7.xsd node/xs:schema jaxb:bindings nodexs:complexType[nameOrderInfo] jaxb:bindings node.//xs:element[nameclass] jaxb:property nameclassField/ /jaxb:bindings /jaxb:bindings /jaxb:bindings這種 node 路徑的寫法和 XPath 非常像其中.//表示從這個復(fù)雜類型下任意層級找元素名為class的節(jié)點(diǎn)。注意property name的值需要遵循 Java 字段命名規(guī)范一般用小駝峰。這里我提醒一點(diǎn)綁定文件本身也要納入版本控制并確保每次 XJC 運(yùn)行時都通過-b參數(shù)指定。命令行是xjc -d ./generated -p dev.example.xsd7.model -b binding.xjb -encoding UTF-8 xsd/xsd-7.xsd如果 binding 文件里寫錯了 XPathXJC 會報(bào)錯說找不到節(jié)點(diǎn)這時多半是schemaLocation或者node寫得不精確??梢园?XSD 文件在 XML 工具里格式化之后用瀏覽器或編輯器自帶的 XPath 輔助確認(rèn)路徑。5.4 用 extension 模式處理 XML Schema 1.1 特性XSD-7 這種新版本契約有時候會用上 XML Schema 1.1 的xs:assert、xs:alternative、xs:openContent等特性。默認(rèn)的 XJC 對 1.1 支持并不好特別是xs:assert因?yàn)樗鼘儆诩s束規(guī)則XJC 基本不會轉(zhuǎn)換到 Java 端。應(yīng)對方法是給 XJC 開啟-extension參數(shù)這樣它能解析更多 1.1 語法避免因?yàn)橛龅讲徽J(rèn)識的元素直接報(bào)錯。xjc -extension -d ./generated -p dev.example.xsd7.model xsd/xsd-7.xsd注意-extension不是萬能鑰匙它只是讓 XJC 放寬了解析范圍對于xs:assert這類規(guī)則JAXB 沒有對應(yīng)的運(yùn)行時校驗(yàn)機(jī)制生成代碼不會自動做這些斷言檢查。如果用得上你仍然需要在業(yè)務(wù)層或者實(shí)際 schema 校驗(yàn)里去處理這些業(yè)務(wù)規(guī)則。6. 生成代碼之后的生產(chǎn)力工作流從“能用”到“好用”XJC 生成完代碼工作其實(shí)只完成了 40%。把生成代碼整合進(jìn)實(shí)際項(xiàng)目并保證長期可維護(hù)性才是接下來真正花時間的地方。這塊我講講自己積累的工作流和習(xí)慣。6.1 生成代碼只讀策略用擴(kuò)展方法而不是改生成文件剛接觸 XJC 的時候我也干過直接修改生成類來加業(yè)務(wù)邏輯的事。結(jié)果就是 Schema 一更新代碼重新生成我改過的邏輯全沒了。后來我定了一個紀(jì)律生成代碼一律不手動修改需要擴(kuò)展行為時要么用XmlJavaTypeAdapter、要么在生成類基礎(chǔ)上做包裝類/擴(kuò)展類、要么用繼承覆蓋共性邏輯。對序列化輸出有特殊要求時優(yōu)先用注解定制而不是改代碼。維護(hù)這份紀(jì)律的最大好處是生成目錄隨時可以刪了重新生成完全無痛。比如需要給訂單類加一個業(yè)務(wù)方法totalAmountWithTax()我不會去動OrderInfo類而是在業(yè)務(wù)層建一個輔助服務(wù)或者用abstract父類做模板。6.2 多模塊項(xiàng)目里把生成代碼隔離成獨(dú)立模塊單模塊項(xiàng)目里把生成代碼放在target/generated-sources直接編譯問題不大。但如果你在做一個多模塊的微服務(wù)項(xiàng)目我建議把 XJC 生成邏輯單獨(dú)放到一個 Maven 模塊里比如xsd-api-model。這個模塊只負(fù)責(zé)承接 Schema 和生成代碼對外只暴露生成的 Java 類型。業(yè)務(wù)模塊依賴這個模塊即使 Schema 更新頻繁、類名發(fā)生變動影響面也只在接口層不會牽扯到所有服務(wù)代碼。這么做還有一個額外好處你可以在xsd-api-model里統(tǒng)一存放 binding 文件和適配器類做到生成邏輯和調(diào)用方隔離。如果未來換了 Schema 版本或改用了新協(xié)議只需要改這個模塊。6.3 自動化校驗(yàn)把 schema 變更納入構(gòu)建門禁我們團(tuán)隊(duì)后來還加了一步在 CI 構(gòu)建里跑mvn generate-sources之后會做一個編譯檢查和 spotbugs 掃描保證生成的代碼沒有低級問題并且和業(yè)務(wù)模塊兼容。Schema 一旦被外部供應(yīng)商修改了本地編譯直接失敗提醒開發(fā)者需要重新評審和適配而不是等代碼里出現(xiàn)一堆不明所以的編譯錯誤才發(fā)現(xiàn)。這種門禁很實(shí)用。我遇到過不止一次外部供應(yīng)商悄悄改了 XSD-7 里某個字段的 minOccurs從 0 改成 1本地沒注意結(jié)果上線之后報(bào)文反序列化到處報(bào)錯。如果每次 Schema 變更都能通過構(gòu)建記錄展示變更差異你就能第一時間發(fā)現(xiàn)這些隱性破壞。6.4 處理 equals、hashCode 和 toString默認(rèn)生成的 JAXB 類是不帶 equals/hashCode/toString 的這給日志打印、斷言測試帶來很大麻煩。插件社區(qū)有兩個常用方案一個是依賴 Lombok在生成后手工補(bǔ)充注解——但這就違反了“不改生成代碼”的原則另一個是使用 JAXB 的XmlTransient基類或者干脆在業(yè)務(wù)層統(tǒng)一寫工具函數(shù)來比較對象字段。我自己常用的方式是寫一個公共工具類用反射比較兩個生成對象的所有字段值。雖然反射有點(diǎn)性能開銷但測試環(huán)境和開發(fā)環(huán)境足夠用。線上如果有復(fù)雜對象比對需求建議用 JSON 序列化之后的字符串來比較直觀且不依賴字段順序。6.5 從舊版 JAXB 遷移到新命名空間的注意點(diǎn)如果你在維護(hù)一個老項(xiàng)目從javax.xml.bind遷移到j(luò)akarta.xml.bindXJC 生成的代碼注解也會變。這個過程看著只是包名替換但實(shí)際涉及很多細(xì)節(jié)XmlRootElement、XmlType、XmlAccessorType等注解的包名都要換ObjectFactory和package-info里的命名空間常量也有變化。最簡單的方式是把 XSD 重新喂給對應(yīng)版本的 XJC 插件生成一遍而不是用文本替換去硬改。我在一次項(xiàng)目升級里試過硬改結(jié)果就是大量編譯錯誤和運(yùn)行時ClassCastException?,F(xiàn)在 JAXB 生態(tài)已經(jīng)分叉了你用的 XJC 版本必須和項(xiàng)目里的 JAXB 運(yùn)行時版本保持同一條主線否則生成的注解和運(yùn)行時對不上啟動時會出現(xiàn)各種“找不到注解”的坑。7. 最后說幾個比較偏門但關(guān)鍵時刻能救命的參數(shù)XJC 命令還有很多參數(shù)我平時用不著但遇到特殊情況能派上大用場。這里列幾個我覺得值得記住的。-nv參數(shù)表示不執(zhí)行嚴(yán)格校驗(yàn)。默認(rèn)情況下 XJC 會對 Schema 做驗(yàn)證如果 Schema 本身寫得不太規(guī)范比如用了過時的語法或者缺少某些聲明命令會直接中止。加-nv可以讓它在盡量寬松的模式下完成編譯。不過要注意跳過校驗(yàn)的結(jié)果是生成的代碼質(zhì)量可能存疑適合在“明知 Schema 有問題但必須先拿到代碼看看”的場景下使用。-catalog參數(shù)用來指定一個 XML Catalog 文件很多項(xiàng)目里會有本地的 DTD/XSD 文件解析依賴。遇到 XSD 文件里的 import 指向一個互聯(lián)網(wǎng)地址公司內(nèi)網(wǎng)又訪問不了時寫一個 catalog 把這些 URL 映射到本地文件就能解掉。-no-header參數(shù)可以生成的 Java 文件不附帶生成時間、版本信息之類的頭部注釋這樣代碼 diff 更干凈也避免每次發(fā)布版本時生成代碼的頭部注釋變化導(dǎo)致無意義的 diff。另外還有-quiet參數(shù)可以減少輸出信息適合在腳本里調(diào)用避免日志被大量警告刷屏。我一般在 CI 腳本里會把-quiet加上方便在全是生成日志的構(gòu)建輸出里快速檢索真正的問題。如果你用的是 Maven 插件這些參數(shù)都有對應(yīng)的 XML 配置項(xiàng)可以對照插件文檔逐一映射。命令行驗(yàn)證好參數(shù)效果之后再落到插件配置里。還有一個值得提的點(diǎn)是XJC 處理xs:any類型時默認(rèn)會生成一個org.w3c.dom.Element成員如果你非要讓那個字段變成Object或者接進(jìn)某個自定義類型只能借助插件或者二次處理。這個問題比較底層大多數(shù)情況下用默認(rèn)的Element類型也夠用但要知道它為什么不是業(yè)務(wù)可以直接使用的強(qiáng)類型對象。8. 一次完整對接流程的實(shí)際操作清單最后我把一次典型的“拿到 XSD-7 到代碼可用”的完整流程列出來給各位一個參照。我?guī)缀趺看螌佣际前催@個清單走穩(wěn)定可靠極少出岔子。第一步先把整個 Schema 文件集放到統(tǒng)一目錄比如項(xiàng)目下的xsd/同時確認(rèn)文件編碼都為 UTF-8。第二步通讀主 Schema重點(diǎn)記錄targetNamespace、外部 include/import 文件、全局復(fù)雜類型和全局簡單類型數(shù)量判斷是否存在命名沖突風(fēng)險。第三步確認(rèn) JDK 版本和 JAXB 坐標(biāo)選擇命令行還是 Maven 插件生成。如果項(xiàng)目本身就是 Maven 項(xiàng)目我強(qiáng)烈建議直接配插件。第四步準(zhǔn)備好 binding 文件顯式指定目標(biāo)包名并對日期、枚舉、沖突命名做定制。第五步執(zhí)行生成命令把生成代碼刷新到 IDE編譯排查語法錯誤。第六步找一個真實(shí)樣例報(bào)文寫 JUnit 測試做一次反序列化和序列化的雙向驗(yàn)證確認(rèn)生成代碼可以和實(shí)際報(bào)文正確匹配。第七步調(diào)整 Schema 版本管理策略正式納入構(gòu)建流程。這套清單看起來簡單但每一步都會攔住一部分人。特別是第六步很多同學(xué)生成完代碼直接就開始寫業(yè)務(wù)等聯(lián)調(diào)的時候才發(fā)現(xiàn)字段映射不對通用的做法是先拿一段真實(shí)報(bào)文跑通Unmarshaller再寫業(yè)務(wù)邏輯。Unmarshaller的使用方式也順便放這里JAXBContext context JAXBContext.newInstance(OrderEnvelope.class); Unmarshaller unmarshaller context.createUnmarshaller(); try (InputStream in new FileInputStream(sample-request.xml)) { OrderEnvelope envelope (OrderEnvelope) unmarshaller.unmarshal(in); OrderInfo order envelope.getOrderInfo(); // 業(yè)務(wù)邏輯... }這樣能確認(rèn)生成類與真實(shí)報(bào)文的字段對應(yīng)關(guān)系是否正確。如果字段類型配錯了或者枚舉對不上在這里就能直接暴露出來不用等到線上。試過這么多方案之后我的核心體會是XJC 生成代碼只是起點(diǎn)真正考驗(yàn)功力的是你如何把綁定文件、構(gòu)建流程、測試驗(yàn)證和代碼隔離這套體系搭好。XSD-7 這類文檔以后還會有新的版本但對 Java 開發(fā)者來說核心邏輯不會變先理解 Schema 結(jié)構(gòu)再用 XJC 把重復(fù)勞動自動化最后用 binding 文件持續(xù)優(yōu)化類型細(xì)節(jié)。這套能力一次投入后面每次對接都能復(fù)用。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
女性喷水高潮在线观看| 韩国成人精品久久久免费看| 亚洲自拍一区夜夜操| 精品一区二区在线针对华人免费观看这里只有精品免费观看 | 性暴力欧美猛交在线直播| 日韩欧美中文字| 丝袜美腿欧美| 天美av在线观看| 伦理片秋霞免费影院| 久久久精品中文字幕爱豆| 亚洲同性aV综合| 天天日美女的B| 麻豆久久视频在线地址| 青青操青娱乐| 九九热男人天堂| 久久婷婷五月综合| 国产又大又粗又色生活片亚洲国产精品成人久久久综合免费 | 麻豆久久久一区二区| 久久久久久久国产a∨| 久久久久久电影| 精品无av| 美日韩一二三区| 116美女午夜| 久久激情五月| 一区二区日韩欧美久久| 热99这里有精品综合久久 | 人人插人人摸人人| 老熟妇一区二区三区…| 亚洲砖码砖专无区2023| 岛国黄色大片网站| 欧美v亚洲v日韩v最新在线二区| 少妇一级无码精品| 操国产逼| 男女性感激情网站| 免费在线黄片视频| 啪啪啪大香蕉| 久悠悠av| 91欧美另类| 91爱看| 96国产污污污丝袜| 久久美女国产| 欧美日韩香蕉| 丁香六月婷婷久久综合| 亚洲限制级| 日本九九久久99| 久久久久久久久国产| www. 男人天堂成人在线| 骚妻少妇精品性色无码四色A V| 国产中文字幕曰本毛片| 五月丁香黄色网| a片久久久久久久久久久久 | 国产AV天美传媒一区二区三区 | 久久伊人亚洲AV无码网站| 国产精品福利资源在线尤物| 黄片色区软件| 欧美少妇一区二区三区| 四虎在线免费视频| 五月天伊人网| 91九色丰满高潮| 欧美性高潮在线| 久久久久久无码人妻中文字幕| 亚洲密乳AV| 欧美老妇曰批的视频| 亚州AV无码国产精品| 99热这里只有精品8| 伊人AAA| 亚洲熟妇乱女区二区三区| 亚洲中文电影| 2019天天干| 久久久久九九九| 天堂精品在线| 欧美影音在线| 91天天| 国产精品久久久久中文字幕| 国产欧美伊人| 欧美视频一| 人妻中文字幕日韩电影| 九九热超碰97亚洲最新香蕉| 国产AV人人夜夜澡人人爽麻豆| 中文字幕免费在线观看| 亚洲女毛多水多21P| 亚洲色堂免费视频| 99国产女人| 26UUU欧美激情一区二区| 五月丁香六月婷综合成人综合| 欧美少妇一区二区三区| 色噜噜日韩精品| 亚洲另类欧美精品| 人妻激情在线视频| 插入逼91| 亚洲全色网| 台湾成人无码AV| 人妻激情偷乱视频一区二区三区 | 91爱看| 日本性爱不卡视频| 一区中文字幕二区日韩| 99rre在线精品99re8| 日韩一区二区精彩视频| 婷色五月天| 日本道日本道中文字幕日本道最新日本道在线观看 | 精品一区二区久久| av在线观看不卡网站| 青青青操| 中文字幕后石码三区四区| 丰满的三级少妇欧美久久久| 国产偷人妻精品一区二区在线| 国产在线视频午夜精华在| 欧美精品日韩一区二区| 黄骗免费网站| 亚州乱码中文字幕综合久久久| 78精品在线| 色播五月婷婷| 999精品乱码| 风骚少妇视频中文字幕| 91成人在线免费视频| www.高清无码诱惑一区.com | 超AV色女| 一区二区精品日韩欧美在线观看| 天天插天天干| 欧美亚州综合网图片| 日韩AV熟女乱伦| 日韩中文9| 日韩偷拍色图| 91日韩| 久久九九99| 超碰欧美COM| 成人美女av| 欧美性综合| 中文字幕性感少妇av| 伊人亚洲综合| 色综合久| 搡老熟女免费视频| 少妇内射www在线观看视频| 国产精品视频麻豆入口| 蜜臀AV成人精品蜜臀AV久久| 老鸭窝在线视频播放| 亚乱色| 一中国女人毛片水真多| 嫩草伊人久久精品| 色综合av男人天堂| 欧美天天干| 啪啪91| 秋霞一级鲁丝片A片| 亚洲丝袜B诱惑| 免费一级毛片在线视频观看| 色九久| 亚洲人妖网| 男男H黄动漫啪啪无遮挡网站| 色香网| www.超碰| 高清无码 国产精品| 久久久久久人| 99啪啪| 精品久久99| 精品久久久av无码免费| 99精品无码| 国产天天骚| 淫荡少妇免费| 秋霞怕怕片| 五月天亚洲网| 大香蕉欧美日韩| 五月丁香啪啪网| 日韩无码视频黄色| 超碰超碰超碰超碰的大鸡吧操黑丝袜| 色欲人妻一区二区在线| 久久久98网站免费视频| 国产版a级片直播在线| 肉动漫无遮挡h在线观看| 日韩精品三级片长长久久| 婷婷久久五月| 亚洲精品影视老司机| 久久伊人影院| 骚日日av| 国产精品对白自产拍| 97天天操天天干| 91性情| 97干天天| 情侣操 逼视频99| 亚洲一区二区麻豆影院| 亚洲高清无码AAA久久久精品| 国产男女边吃边摸视频网站| 九九热精品| 东方亚洲在线操逼天堂| 蜜臀色乳| 久久超碰98| 毛片视频白嫩| 亚洲综合影视| 亚洲精品丝袜| 99RE在线视频精品,这里只有精品| 久热无码| 午夜精品久久久99| 人人澡人人爽人人精品| 日韩女优在线| 中文字幕视频2区| 91欧洲国产成人久久精品网站| 天美传媒av 在线| 天天干夜夜一操| 国产高清自拍视频| 色欧洲| 色九久| 国产一二三福利视频网| 色妇综合网| 综合网亚洲| 78精品| 综合亚洲欧美| 久久久蜜桃臀无码视频| 天天澡天天爽日日AV| 96麻豆精品一区二区三区| 少妇久久久免费| 9 1超碰九色| 精彩久久中文| 可乐操在线| 久区视频| 精品对白久久不卡| 精品一区二区三区蜜桃臀赵总 | 欧美综合97www| 高清国产av无码| 色哟哟av| 91福利网在线观看| 麻豆 美女 丝袜 人妻 中文| 97精品人妻一二三四| 97中文字幕一区| 欧日韩一二三f区| 成年在线视频日本亚洲在线视频区精品江靖宇公司 | 超碰在线观看av不卡| 国产女人和拘做爰视频 | 国产黄a三级三级三级av在线看 | 9色国产精品一区粉嫩| 综合一区二区影视| 小草av不卡亚洲二区| 午夜天堂网| 色香伊人| 伊人国产成人av网站| 午夜精品久久一区二区| 日本裸体久久色噜噜| 青青草密桃在线播放| 久久欧洲| 青青草公开在线免费不卡视频| 亚洲男人的天堂va亚洲男人社| a片 xxxx受爽视频| 可以在线观看的黄色网址| 天天干夜夜一操| 婷婷综合五月天| 又黑又大又粗| 日产成人久久| 岛国免费视频在线| 欧美成人黄网色网站| 久久久久深夜无码| 中文字幕一区二区三四五区日日骚| 久操在97| 一起草三级AV电影在线观看| 奇米狠999| av一区二区三区 中文| 久久久久久亚洲精品中文字幕人妻| 蜜臀99999| 五月天AV资源| 看免费的黄片| 中文字幕日韩综合| 天天干夜夜| 欧美AAAA黄片| 97人妻色| 亚洲色图日韩丝袜制服一区二区五月在线| 无码不卡八戒| 久久久九九九九| 91精品综合久久久久久五月丁香| 天操天操夜操夜月操月年年操| 日韩精品人妻中文字有码在线 | 欧美一区二区三区互相| 五月婷丁香| 人妻超碰青青草98| 91丨九色丨国产丨人妻在线| 亚洲 中文 女同| 欧美日本不卡在线| 韩国一级婬片A片AAAAA| 日韩专区数据列表-第3230页-精品国产一区二区三区香蕉 久久99熟女人妻中文字 | 婷婷久久五月天| 玖玖资源中文字幕制服丝袜| 又大又大又大又粗爽高潮观看| 日本三级R| 99热日| 岛国福利在线精品播放| 亚洲欧美天堂在线| 精品人妻一二三| 丁香五月婷婷基地| 九九五月天| 久久精品国产亚洲AV无码电影| 国产高清不卡视频| 四虎国产精品永久入口| 一区中文字幕二区日韩| 中文人妻av高清一区| 中文字幕在线观看网页| 国产久久久9999| 9118禁| 五月花婷婷| 久久久久久久久久久久色网| 视频二区美腿丝袜制服人妻欧美| 欧美色涩| 欧美日韩一干二干| 国产精品欧美日韩久久| 东京热99999| 精品久久久久久中文| 中出后入| 欧美性爱另类综合| 国内毛片欧美香蕉精品| 妇女视频网站| 色综合av男人天堂| 99re99| 极品久久久久久久久久久久久久| 精品成人亚洲午夜电影| 久久精品一区一起草| 亚洲AV免费在线| 久热这里只有精品9| 天天插天天射| 你懂的在线观看区国产| 97超碰色中文字幕| 天天色粽合合合合合合合| 青青草福利视频| 综合 青草 伊久久 影院 综合| 国产日韩区| 欧美在线|亚洲| 99精品在线观看| 看日韩黄片| 久久精品中文| 蜜臀少妇一区二区| 欧美日日操| 欧美另类天堂| 色香AV| 中文字幕丝袜人妻| 伊人网综合在线视频| 99热国产精品| 99抽插| av一区二区三区 中文| 91丨人妻丨国产丨丝袜| 亚欧美色图| www四虎| AA特级绝黄| 久久久9视频| 国产精品麻豆视频网站| 毛片99-全集电影手机免费观看完整-B029AV | 91爱网| 淫骚熟女一区二区三区| 好吊妞转入那个网| 韩国三级理论在线| 中文字幕乱码人妻一区二区三区,99精品| 激情 欧美 亚洲 小说| 欧美在线第五页| 久久精品72| 人妻熟女午夜精品在线| 一级特级aaaa毛片免费观看| 国产高清自拍| 男人的天堂com| 欧美 亚洲 另类 综合| 亚洲色图在线视频| 午夜福利久久久噜久噜久久综合| 超碰在线一区| 天天操熟妇| 91爰爱欧美| 天天操女人| 九九色精品| 婷婷丁香一区二区三区| 亚洲少妇喷视频看| 日日爽夜夜爽| 99这里有精品视频| 91色婷婷综合久久中文字幕二区| 久久毛卡| 久久美女国产| 十八禁av无码免费网站APP| 可免费观看的av毛片中日美韩| 99在线精品观看视频中文| 一区,二区,三区视频| 成年男人的天堂| 操少妇很爽av| 亚洲日韩青青草色月| 五月天色图影视| 高清无码国产亚洲| 亚洲熟女av日韩熟女| 日韩成人性日韩成人性爱视频在线免费观看| 激情内射| 91综合无码| 亚洲色性| 久久久96| 免费家庭乱伦视频| 国产 亚洲 一二三四| 国产精品久久久啊| 内射夫妻三片| 一级特黄aaa大片在线观看成人一级片在线观看 | www.婷婷| 超碰79人人乐| 丝袜狠狠草尤物人妻av91| 青青草视频这里只有精品| 久久久人体| 亚洲城人男人的天堂| 欧美无圣光在线| 男人久久精品| 日韩一性一交一A片俄罗斯| 无码人妻精品一区二区中文| 啪一啪免费视频| 五月天婷精品激情| 六月婷婷五月丁香| 99蜜桃臀亚洲成人在线观看| 天天综合网~91综合网| 日本三级精品| 超碰免费人妻人人| 一本色道久久综合亚洲二区三区| 99热免费| 亚洲图片日本AⅤ欧美在线| 凹凸视频在线一区二区| 国产一区二区在线播放量| 射丝袜大香蕉| 少妇精品久久久| 久久精品高清无码一区| 久久嫩草| 91久久精品中文字幕| 97摸视频| 不卡人妻少妇精品毛片一区23区视频| 老女人碰碰在线碰碰视频| 精品国产综合久久福利,热99这里有精品综合久久,99热这里只有免费国产精品,精 | 97chaopengongkai| 日韩99精品视频综合区| 九九色婷婷| 丰满人妻一区二区三区在线| 色97综合中文字幕| 1769一区| 久久婷婷五月综合| 韩日巨乳美女免费视频在线观看| 久久99深爱久久99精品| 人妻精品一区二区| 国产一级作爱毛片| 国产女同性恋视频| 久久高潮妇女视频| 欧色综合| 91精品国产91熟女| 国产精品久久久久久 百度| 91久久久久免| 啊啊啊啊好大好硬啊啊啊啊啊| 99少妇| 日本三级A片网站com| 激情五月天色色| 亚州中文字幕超碰97| 亚洲欧美另类少妇精品| 欧美综合1性辶| 91狠狠综| 毛片电影一区二区三区| 国产AV线| 欧美性爱日韩性爱| 少妇同性| 上特色A在线| 婷婷五月av| 青操影院| 可能人人看人人摸| 青青草精品| 加勒比海色香蕉婷婷| 美女黄频a美女大全免费皮| 欧亚不卡| 亚洲国产精品无码AV久久久| 性色一线| 久久久久夜夜夜夜| 97久久精品亚洲| 欧美色蜜桃97| 欧美成va视频网站| 欧美视频一区二区三区| 留下AⅤ黄色片| 韩日精品福利视频一区不卡在线免| 凹凸视频在线一区二区| 99青草| 欧美日韩在线小说 | 日日日日做夜夜夜夜无码| 啊好大好舒服| 久久精品国产亚洲妲己影视| 熟女自慰久久久| 日韩欧美大片免费高清啪啪| 久久黄黄| 欧美色欧美| 操九九九九九九| a级免费在线观看| 欧美精品在线观看| 伊人五月天婷婷| 色五月第四色| 亚洲午夜福利在线影院| 精品二区久久| 无码免费一区二区三区啪啪| 精品人妻一二三| 中文字幕在在线观看网站| 国产一区二区三区高清视频| 97色色,97综合| 盗摄女人妻在线| 福利天天都操| 97人妻色| 国产精品国产自产高清AV| AV中文字幕剧情1区2区3| 男女激情黄色网址| 高清无码人妻久久久一区二区三区aⅴ| 婷婷综合| 国产一区二区免费福利片| 大香蕉欧美日韩| 人妻激情偷乱视三区频一区二区| 国产精品伦理| 三级片大波波| 狠狠操综合| 成人八戒网站| 亚洲小说视频| 久久超碰、| 国产九九九九九九九九| 亚洲在线91| 日韩精品怡红院| 色婷婷成人| 国产隔壁老王影院在线| 麻豆 亚洲 97| 99热免费| 日韩精品免费高清视频在线| 91黑人狂躁丰满熟妇| 97干天天| 免费夜夜爱黄色视频毛片| 国产精品分类在线观看| 97爱爱官网| 国产最新AV| 国产成人手机视频激情| 偷拍综合网| 91视频综合在线| 操我啊啊啊啊啊| 婷婷影院入口| 精品国产91av一区二区三区| 亚欧美色| 热G综合热G中文| 啊啊啊啊在线观看网址| 中文字幕二区日韩天堂| av资源在线播放天堂| 日韩福利综合一区| 综合网 欧美| 欧美一区二区三区成人性生活| 国产欧美美女免费观看视频| 睡产熟女乱伦| 国产人妖视频一区在线观看| 午夜成人爽爽爽爽A片李冰冰| 啊啊啊啊啊啊啊在线| 国产suv精品一区二区四| 人妻精品一区二区在线| 精品少妇人妻av久久免费| 国产精品人妻无码久久久互動交流| 超碰这里有精品| 日韩在线97| 99精品丰满人妻无| 91neishe| 天美精品av| 中文字幕 码精品视频网站| 黄在线| 成人性爱视频在线看| 一区二区免费电影久久| 欧美视频一| 日韩兔费看黄片| 好爽免费视频| 91性网| 天天干夜夜鈤| 国产精品视屏| 国产成人在线观看网址| 最近二区三区视频大全| se..亚洲欧美| 人人性爱视频免费| 操操逼视频| 日韩性爱视频在线免费观看| 亚洲图片色图欧美另类| 嫩呦国产一区二区三区AV| 亚洲黄色视频在线观看视频| 看免费的黄片| 亚洲成人美女无吗| 婷婷中文网| 亚洲欧美国产其他二区| 成人av免费观看| 久久久久免费少妇| WWW4虎| 欧美日韩大陆黑人少妇99| 欧美色日本| 激情四射婷婷六月天| 久久九九久精品国产尤物|国产精品爽黄69天堂A片潘金莲,国产亚洲精品第一综合 | 精品然女一区二区| 久久精品中文字幕女同| 91熟女视频网| 97视频在线看| 国产极品精品美女视频| 五月天丁香婷婷综合网站| 高清在线偷拍自拍视频| 成 人 影视 一区 二区 三区 四区| 国产suv精品一区二区四| 亚洲黄日韩无码专区| 婷婷美人网| 91 亚欧| 玖草在线视频| 亚洲精品一二区| 99热欧美| 人人超碰在线观看黄| 97草草| 亚洲欧美999| 中文字幕一区二区三区高清| 成人午夜视频免费播放| 亚洲熟女国产综合另类| 熟女久久久| 国产精品白丝| 一区二区三区免费岛国片| 久久人妻精品| 久久同城AV| av网站在线看| 激情久久久| 亚洲精品影视老司机| 日本韩欧美在线播放a| 五月丁香网站| 亚洲精品蜜桃久久久久久久| 精品免费囯产一区二区三区| 操逼日批| 男人兔费天堂| WWW美腿丝袜香蕉中文| 熟妇乱伦一区二区| 亚洲免费人妻在| 青青草日本中文字幕| www.人人摸在线视频| 1人人看人人摸人人操| 亚洲色图久久成人| 97精品一区二区视频在线观看| 三男一女不戴套的A片| 大香蕉九九| 色偷偷男人的天堂麻豆| 日日操免费视频| 大奶啊啊好爽 | 99综合视频一体| 偷拍超碰| 天天看精品动漫视频一区| 色官网在线| 中文字幕日韩综合| 日产精品久久久一区二区| 中国zzijzzijzzwww精品| 中文字幕一区二区三区人妻少妇在线| 97操97干| 大香蕉五月天| 蜜臀网址在线| 7777欧美成是人在线观看| 91天美传媒在线| 亚洲av无码国产精品字幕| 精品久久久无码| 黄色工厂这里只有精品| 柠檬AV导航| 超碰导航97| 睡产熟女乱伦| 亚洲在线观看| 麻豆啪啪啪视频| 熟女91网| 日韩中文字幕二区| 色欧美在线| 日本黄 R色 成 人网站| 99热线麻豆 | 精品国产综合久久福利,热99这里有精品综合久久,99热这里只有免费国产精品,精 | 五月丁香在线| 久久系列| 欧亚乱色熟一区二区三四区| 人人么人人操| 日韩二三区| 久久午夜鲁丝片| 磁力99AV| 嫩草一区二区在线观看| 日韩熟女视频二区| 毛片电影一区二区三区| 一区二区三区看视频| 久久性爱视频| 亚洲网站一区二区在线| 久久精品72| 亚洲成人福利电影免费| 四虎精品永久在线观看| 亚洲AV无码天美传媒一区| 香蕉欧美| 伦在线97| 欧美婷婷| 操b在线观看| 熟女网站最新| 婷婷伊人| 国产美女自拍AV| 国产91专区| 伊人AAA| 日韩一级欧美一级国产一级台湾 | 黄色人人| 91女色| 色91综合网| 久久婷婷综合国际产色怕| 91亚洲图片| 亚洲自拍欧美国产首页网曝| 亚洲最大无码中文字幕网站| 老熟女网站| 97精品国产手机| 狠狠操狠狠爱| 丁香六月激情| 久久久精精精| 国产第二页| 亚洲一区二区麻豆影院| 亚洲天堂中文字| 欧美亚洲特P| 91中文精品日韩欧美在线| 亚洲日韩成人性爱视频| 午夜舔阴达高潮视频免费看| 超碰在线1234区| 熟妇人妻一区二区| 国产精品熟女丝袜一区二区| 超91综合网| 日韩性爱视频在线免费观看 | 久久麻豆一区二区| 2021久久国产综合精品青草| 亚洲天天操| 941超碰| 欧美色图私拍91| 超碰av在线| 人人摸人人添人人操| 欧美性第一页| 懂色AV网| 国产女主播视频在线观看| 国产suv精品一区二区四区999| 亚洲日本韩国在线| 五月婷网站| 日韩欧美性爱电影在线观看| 中文字幕一区二区三区四五区| 久久一区,青青青青草视频在线播放| 狠狠操综合| 无码聚合| 日韩一级成人毛片免费观看| 日韩欧美大片免费高清啪啪| 欧美日韩在线小说 | 久操97| nuu12国产麻豆精品| 97 国产一区| 伊人久久亚洲中文字幕| 99热网站| 色噜噜婷婷| 九九色图| 亚洲中文字幕av| 91free福利| 天天草天天干天天日| 草草网站影院白丝内射| 中文字幕日韩人妻视频一区二区三区 | 91综合网在线| 欧美自拍网| 欧美高清91| 欧美情色亚洲| 97资源亚洲| 91A欧美电影网站| 亚洲不雅视频1区二区| 蜜臀99久久国产| 夜夜欧美 | 一个色导综合| 日韩欧美大力操| 青草草免费网站av| 成人麻豆av电影网站| 国产AV色黄看到爽| 91艹B视频| 欧美一区二区观看在线| 婷婷AV一区二区三区| 久久婷婷色| 日日操天天操| 亚洲免费精品一区| 国产AV天美| 蜜臀久久久| 亚洲天天影视色综合| 九草九九九| 91天美免费| 91亚洲人| 国产精品第一区第一页| 人人 操人人 操人人| 中日韩久久久| 成人av免费观看| 婷婷成人久久久精品| 欧美性色综合网| 91艹| 亚洲熟妇A V黑人| 国产精品福利资源在线尤物| 日韩乱伦影音先锋| 99re视频在线观看这里只有精品| 亚洲小说视频| 国产综合在线视频网站| 国产1769在线| 超碰亚洲97| 久草精品视频| 日本综合色图| 95自拍视频在线观看| 中文字幕在线高清男人的天堂| 中文字幕在线观看丝袜| 成人五月天色网| 校园春色美腿丝袜| 人人人摸人人| 五月天综合在线| 97人人爱人人做人人乐| 大香交| 91AV入口| 四虎影院成年人片| 国产又大又粗又长视频在线| 96一区二区三区| 被男人吃奶很爽的毛片| 五月综合久久| 国产欧美日韩臀| 97超碰9| 日韩 欧美 视频 在线 一区| 99国内精品| 久久成人东京热人妻| 欧美不卡在线一区二区| 色婷婷五月天| 大白逼三四级| 8x福利精品第一福利视频导航| 97在线视频观看| 极品AV网站在线观看| 欧美黑人极品高潮喷吹熟女黑人性暴力日韩在线欧美极品一区二区老师黑人潮喷一 | av72网| 国产精品电影大全| 国产 码在线成人网站| 超碰98综合网| 人人么人人操| 国产伦精品一区二区三区视频女| 97天天在线| 欧洲欧美视频一区二区| 96AV精品| 久久在肏| www超碰| 久久久91福利姬| 伦伦成年午夜免费视频| 日韩/97| 丁香婷婷五月| http://qxhbdz.com| 东北老熟女| 人人考人人摸人人干| 99热8| 97人妻免费中文字幕| 天天舔九色婷婷| 国产精品爆乳懂色蜜乳| 色嘟嘟人妻天堂网| 国产精品噜噜噜日日日| 国产67194| 夜夜高潮夜夜爽国产伦精品| 国产综合网站在线播放| 中文在线视频| 亚洲日韩欧美一区二区| 最新av网站在线观看| 免费农村成人少妇人妻Aa一区二区视频| 78精品| 啊啊啊啊嗯嗯嗯用力好爽 | 偷拍伦理视频| 国产女人视频三四五区| 男人的天堂2018东京热啪啪啪| 欧美+日产+中文| 欧美一级三级| 欧美色狠| 天天干天天日天天射黄色片| 国产中文大片资源中文字幕 | 一本大道不卡一二三区| 97精选久久| 国产精品成人无码av无码免费| 99最新日韩偷拍视频| 日韩乱插| 人人妻人人玩人人澡人人爽| 精品人妻二区三区| 欧美日韩啪啪电影| 亚洲精品 欧美精品| h无码动漫在线观看| 夜夜夜夜爽| 久久九色| 久久久久九九九九| 日本天天人人狠狠在线日美女 | 精品一区二区三区蜜桃臀赵总 | 国产黄色 A 片免费看| 亚洲。天堂。日本在线观看| 色婷久久| 欧美日韩国产成人高清| 97资源免费视频| 深夜激情无码| 欧美色亚洲| 噜噜噜亚洲精品| 婷婷色播婷婷| 日韩操逼性鲍| yazhouzaixian| 嗯啊免费视频| 日本欧美一区二区三区免费| 青青操在线视频| 97色论| 在线v中文字幕一区二区三区| 色欲久久99国产精品久久久久久| 97人人中文网| 免费A V在线| 一中国女人毛片水真多| 91青青在线视频| 一区二区三区 丝袜 高跟 美腿| 亚洲 日本 国产 综合| 成年在线视频日本亚洲在线视频区精品江靖宇公司 | 亚洲精品一区二区三区新线路| 亚洲自拍天堂| 青娱乐黄色录像| 人妻人妻天天碰| 久久99操天天日| 欧美性爱日韩性爱| 97aiaiai| 蜜臀99久久精品久久久久久| 日本啊啊啊啊啊视频| 婷婷久草| 操逼www.| 日本成人免费一区二区三区| 欧美丝袜亚洲| 91欧美丨精品丨入口| 久久精品人体AV| 91成人久久 | 超91综合网| 亚洲精品日韩国产欧美| 日韩免费三级黄片电影| 午夜人妻精品综合在线| 一区二区三区免费岛国片| 日韩性爱啪啪视频| 色综合天天爱去电影网| 欧美骚少妇| 97色涩| 亭亭丁香激情| 99re6久热只有精品6在线直播 | 夜夜高潮夜夜爽国产伦精品| 大香蕉综合久久| 成人AV素股で擦久久| 99热精品在线| 午夜男女爽爽爽在线视频 | 午夜九九| 久久精品一区二区三区蜜桃臀| 青青草精玖玖69精品| 欧美视频在线第3页| 午夜丁香婷婷| 日韩另类| 国内毛片无码一级毛片| 精品性爱一二三区| 精品国产91av一区二区三区 | 97色涩| 精品十三区| 91丝袜美腿网站| 91久久精品国产| 久99久视频精选| 97人肏| 91亚洲精品青草| 95精品在线| 久久人人妻| 久久久com| 中文字幕一区二区三区蜜臀| 男人的天堂2018东京热啪啪啪| 亚洲情色91| 人妻夜夜爽天天爽麻豆三区网站| 精品人妻1237| 丝袜喷水在线| 亚洲美女 晚间男人天堂 | 成年无码动漫av片无尽在线| av激情亚洲五月天| 午夜小电影在线插入淫高潮| 欧洲黄色网| 亚洲无码太久| 白天啪啪晚上啪啪视频| 欧美亚洲尤物久久| 国产AV高清AV无码| 超碰国产在线| 免費人妻夜夜爽天天爽爽一区| 欧美高清性猛交| 91/欧美| 日夜尻逼网| 99热这里只有精品18| 超碰在线人人射| 国产一区二区三区免费视频在性观看| 亚洲图片婷婷五月天| 天天色天天干天天射| 成人三级片无码| 一本道综合色图| av亚洲天堂资源网站| 97视频在线免费播放| 色欲天香天天综合网-成年人三级片网站-欧美乱妇狂野-日韩国产专区-久久久久久 | 久久精品无码不卡| 2017天天插| 国产亚洲精品精AV.| 欧美aaaaaaa| 五月天婷婷小说| 欧美第38页| 熟女熟妇伦久久影院毛片一区二区| 天天日骚逼熟女| 91丝袜在线观看| 人人看欧美性爱| 99精彩视频| 久草婷婷| 久久9精品| 国产亚洲欧美每日在线| 立川理惠加勒比无码| 中文字幕丝袜美腿| 亚洲情色综合网| 97超碰欧美| 国内毛片国产专区二| 国产av白丝| 熟女熟妇伦久久影院毛片一区二区| 久久97精品久久久久久久不卡| 国产精品久久久久久久AV大片| 第一高清av中文字幕| 天天做天天爱天天爽AV| 日天天九九天堂666| 亚洲精品一区二区精品| 五月天激情四射| 91天射| 欧美成人性活片| 无码乱人伦中文视频| 久久久久密| 天天夜夜rb| 蜜桃视频成a人v在线| 精品国产一区二区久久| 啊啊啊 在线| 国产探花精品在线| 99.色网| 亚洲色交| 亚洲成人性爱在线观看| 久久视网78| 超碰九7| 丁香九月激情| 亚洲人精品午夜不卡| 美女视频尤物网在线看| 91爽啪| 人妻91少妇| 囯产操逼片| 国产第二页| 一区操逼| 麻豆婷婷成人一二三| 丰满少妇一区二区三区免费看| 3p国产色噜噜一区| 久久久久国产| 久久久久亚洲av综合波多野制衣| 按摩中文字幕| 国产女人视频三四五区| 成人看片网站| 密臀在线视频| 成人性爱电影一区二区| 本道在线| 久久久久久久国产a∨| 狠色婷婷久久一区二区三区_| 伊人热综合| 区一在线观看| 国产一级舔足在线观看| 天堂av2019| 乱伦熟女论坛| 国产久久视频| 操操操五月天婷婷丁香影院| 亚洲。日韩。欧美| 欧美极品美女aaaaaa级黄片| 毛片视频白嫩| 欧美性爱第一页久久| 中文字幕乱碼在线| 亚洲精品白浆高清久久久久久 | 在线一道啪| 日韩乱伦影音先锋| 色网1| 国产精品香蕉热久久新品| 亚洲男人天堂2| 中文字幕狠狠玩| 91操熟女视频 | 操国产高清| 精品人妻一区二区免费蜜桃| 日本操逼视频不卡直接放| 亚洲免费97免费| 黑人嘿嘿嘿超爽免费视频| 综合大香蕉美。| 99视频只有精品| 久草加勒比一区在线| 91美腿丝袜在线观看| 人妻偷拍一区二区三区| 亚洲日韩东京热一区| 欧美黄片视频在线观看免费 | 日本欧美国内在线| 大香蕉久久| 四虎AV影视国产精品亚洲精品| 91av一区二区在线观看| 超碰无码五月97| 色五月综合网| 国产在线观看一区二区三区| 国产精品久久久777| 嫖老熟女A片一二三区| 91天天综合日韩欧美| 综合激情97| 91成人精品在线播放| 东京太热男人的天堂久久久| 亚洲欧洲美腿丝袜| 欧美性爱中文字幕无线码| 欲综合网| 神马午夜久久久| 欧美性生活综合| 亚洲无码com| 大香蕉青青9| 亚洲成人av色网| av在线观看不卡网站| 久久线上视频免费看| 综合网亚| 99热超碰在线| 国产91av在线播放| 加勒比无码毛片| 国产青视频| 久/久精品99看9| 欧美精品一区二区少妇免费A片| 91模特在线观看| 色诱avtt| 日韩人妻精品久久久久| 久久亚洲AV无码专区首页| 欧美乱欲| 无码精品啪啪啪一区二区三区三州| 久久大香蕉手机高清| 欧美午夜视频精品久久| 亚洲中文字幕熟女| 青青草华人在线欧美在线| 久久久久一本一区二区青青蜜月| 黄色av片三级三级三级免费看| 中文字幕国产在线天堂| 97在线亚洲| 亚洲视频二区 | 久久中文字幕女同性恋一区| 大香蕉十区| 九九这里只有精品| 十八禁成人网站在线观看| 欧美人人操人人插| 91色宗合| 欧美偷| 欧美少妇高潮久久91| GVH-003 母子姦 青木玲-麻豆视频,麻豆视传媒短视频网站入口,麻豆视传媒官网直 | 五月婷色| 久久久久13| 青娱乐久久艹| 欧美精品日韩久久久九| 五十路熟女人妻一区二区在线观看| 日韩二区三四区五区六区在线看| 亚洲AV无码| 九九九九九九九精品视频| 强免费黄色网址| 国产精品色片一区二区| 色翁荡息又大又硬又粗又爽| 亚洲天堂精品日韩电影| 黄色工厂这里只有精品| 熟妇一区,二区,三区。| 青青草久草AV| 无码久| 婷婷情色五月天| 综合网久久| 91jk色拍| 日本A级视频| 久久伊人网视频一区二区三区 | 青青草在线视频美女| 中文一区二区| 天天操美美| 99热日| 天天日熟妇| 免费国产| 91中文字幕在线观看| 91综合天天看| 精品十八在线观看| 亚洲精品97p| 天天干夜夜鈤| 国产97免费视频| 欧美亚洲激情| 中文AV制服乱伦| 日韩熟女无码| 7777奇米影视久久| 人人操人人搞人人草| 干干干天天| 综合欧美日本三级| 97干在线视频| 亚洲精品 大香蕉| 日韩美女久久一区二区三区| 中文字幕视频在线观看一区二区| 无码欧美有限公司| 中文有码第五页| 欧美人人天天网|