亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

如何利用Jackson序列化忽略指定類型的屬性詳解

2024-07-14 08:42:44
字體:
來源:轉載
供稿:網友

前言

本文準確來講是探討如何用 Jackson 來序列化 Apache avro 對象,因為簡單用 Jackson 來序列化 Apache avro 對象會報錯。原因是序列化 Schema getSchema() 時會報錯,后面會講到,需要序列化時忽略該屬性。那么能不能在 getSchema() 上加上 @JsonIgnore 來忽略該屬性呢?原理上是通的。不過手工修改的 avsc 生成的 Java 文件隨時會因為重新編譯而還原,所以不太具有實際可操作性,當然通過定制編譯 avsc 用的模板文件來加入 @JsonIgnore 是另一回事。

由于不能在要忽略的字段上添加 JsonIgnore 來控制,而如果我們明確了要忽略的字段類型的話,是能夠定制 Jackson 的  ObjectMapper  來屏蔽某個特定的類型。來看下面序列化 Apache avro 對象的例子:

假設我們有一個 Apache 的 Schema 文件 user.avsc, 內容如下:

{ "namespace": "cc.unmi.data", "type": "record", "name": "User", "fields": [ {"name": "name", "type": "string"}, {"name": "address", "type": ["string", "null"]} ]}

編譯用 avro-tools compile schema user.avsc . 生成 cc.unmi.data.User.java 源文件,當我們試圖對類型的對象用 Jackson 進行序列化時

ObjectMapper objectMapper = new ObjectMapper() ;User user = User.newBuilder().setName("Yanbin").setAddress("Chicago").build();System.out.println(objectMapper.writeValueAsString(user));

收到異常(關鍵信息)

Caused by: org.apache.avro.AvroRuntimeException: Not a map: {"type":"record","name":"User","namespace":"cc.unmi.data","fields":[{"name":"name","type":"string"},{"name":"address","type":["string","null"]}]}
    at org.apache.avro.Schema.getValueType(Schema.java:294)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:664)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:689)

從上面的錯誤可以定位到 Jackson 的試圖序列化 User 對象的

 public org.apache.avro.Schema getSchema() { return SCHEMA$; }

而 org.apache.avro.Schema 中的 getValueType() 直接拋出異常拒絕被歸化

 public Schema getValueType() { throw new AvroRuntimeException("Not a map: "+this); }

因此,要實現序列化 Apache avro 對象,解決的辦法有三

  • 凡是 org.apache.avro.Schema 的屬性不被序列化(Schema 輸出確實用處不大)
  • 或對于org.apache.avro.Schema 類型的屬性定制序列化,比如輸出為完整類名,或 Schema 定義的文本內容
  • 再來一個,對 SpecificRecordBase 類型的 schema 名稱的屬性進行忽略(avro 類型繼承自 SpecificRecordBase)

它們的實現分別如下

忽略序列化指定類型的屬性

先定義一個標注了 @JsonIgnoreType 的注解

@JsonIgnoreType@interface IgnoreAvroSchemaField {}

序列化 Apache avro 對象前給 ObjectMapp 加一個 mixin

ObjectMapper objectMapper = new ObjectMapper() ;objectMapper.addMixIn(Schema.class, IgnoreAvroSchemaField.class); User user = User.newBuilder().setName("Yanbin").setAddress("Chicago").build();System.out.println(objectMapper.writeValueAsString(user));

有了上面高度行的代碼,這兒的 Apache avro User 對象就能被正常序列化了,輸出為

{"name":"Yanbin","address":"Chicago"}

這樣 getSchema() 返回的類型,或另何對象中有 org.apache.avro.Schema 類型的屬性都會在序列化時忽略掉

定制 Schema 屬的輸出內容

對于 Schema 類型的屬性,除了前面采取堵的方式,還可以因利疏導,即定制 Schema 屬性值的輸出內容

定制化 Schema 序列化方式

class AvroSchemaSerializer extends JsonSerializer<Schema> {  @Override public void serialize(Schema value, JsonGenerator jgen, SerializerProvider provider) throws IOException { jgen.writeString(value.getFullName()); //直接輸出當前 Apache avro 對象的全限類名 }}

給 ObjectMapper 加上定制的序列化器

ObjectMapper objectMapper = new ObjectMapper() ;SimpleModule simpleModule = new SimpleModule("SimpleModule", Version.unknownVersion());simpleModule.addSerializer(Schema.class, new AvroSchemaSerializer());objectMapper.registerModule(simpleModule); User user = User.newBuilder().setName("Yanbin").setAddress("Chicago").build();System.out.println(objectMapper.writeValueAsString(user));

序列化后產生的輸出如下

{"name":"Yanbin","address":"Chicago","schema":"cc.unmi.data.User"}

如果在 AvroSchemaSerializer 把 jgen.writeString(value.getFullName()) 替換如下

 jgen.writeString(value.toString());

并且序列化后對內容進行格式化輸出

 System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(user));{ "name" : "Yanbin", "address" : "Chicago", "schema" : "{/"type/":/"record/",/"name/":/"User/",/"namespace/":/"cc.unmi.data/",/"fields/":[{/"name/":/"name/",/"type/":/"string/"},{/"name/":/"address/",/"type/":[/"string/",/"null/"]}]}"}

指定特定對象的屬性名進行過濾

從語義上除了 Ignore 外,Filter 也像是干這事的,可以嘗試過下面的方式, 分兩步走

定義一個帶 @JsonFilter 的注解,也是不顯示注解到任何類

@JsonFilter("filter out apache avro schema field") //字符串值要與下面 addFilter("xxx") 保持一致class PropertyFilterMixIn {}

給 ObjectMapper 設置 filter

 ObjectMapper objectMapper = new ObjectMapper() ; objectMapper.addMixIn(SpecificRecordBase.class, PropertyFilterMixIn.class); //對 SpecificRecordBase 類型的對象應用 FilterProvider filterProvider = new SimpleFilterProvider() //對 SpecificRecordBase 類型(如 User) 的名為 "schema" 屬性屏蔽  .addFilter("filter out apache avro schema field", SimpleBeanPropertyFilter.serializeAllExcept("schema")); objectMapper.setFilterProvider(filterProvider);  User user = User.newBuilder().setName("Yanbin").setAddress("Chicago").build(); System.out.println(objectMapper.writeValueAsString(user));

輸出效果沒有意外,也能避免序列化 schema 屬性

{"name":"Yanbin","address":"Chicago"}

這最后一種方式是本篇寫作行將結束時找到并驗證的,所以不寫出來,不進行梳理可能永遠只會第一種方法。

鏈接:

  • Jackson Ignore Properties on Marshalling
  • How do I exclude fields with Jackson not using annotations

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VeVb武林網的支持。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
少妇av一区二区三区| 国产日韩欧美一二三区| 日韩精品免费在线观看| 欧美精品videossex性护士| 91免费电影网站| 欧美极品少妇xxxxⅹ裸体艺术| 亚洲国语精品自产拍在线观看| 欧美裸身视频免费观看| 青草青草久热精品视频在线网站| 亚洲国产精品国自产拍av秋霞| 日韩中文av在线| 91精品国产乱码久久久久久久久| 成人黄色在线播放| 欧洲永久精品大片ww免费漫画| 国产aⅴ夜夜欢一区二区三区| 亚洲成色777777女色窝| 国产一区二区三区高清在线观看| 中文字幕国产精品久久| 亚洲在线视频观看| 日韩毛片中文字幕| 亚洲成人激情图| 国产91精品在线播放| 欧美性猛交xxxx黑人猛交| 久久久久久久国产精品| 免费av一区二区| 欧美成人免费大片| 91精品国产成人www| 亚洲精品福利视频| 国产精品第2页| 欧美在线性视频| 日韩在线观看精品| 日本在线观看天堂男亚洲| 国产精品热视频| 亚洲自拍偷拍网址| 久久久久久国产三级电影| 色天天综合狠狠色| 欧美日韩黄色大片| 国产在线精品播放| 亚洲国产精品久久91精品| 久久久女人电视剧免费播放下载| 亚洲无av在线中文字幕| 精品久久久久久久久久久久久| 欧美激情综合色| 欧美丝袜一区二区| 亚洲国产精久久久久久久| 日韩一区二区欧美| 国模精品视频一区二区| 97视频国产在线| 欧美激情国内偷拍| 中文字幕不卡av| 午夜欧美不卡精品aaaaa| 亚洲国产精久久久久久久| 精品成人在线视频| 国产精品大片wwwwww| 中文字幕免费国产精品| 欧美高清激情视频| 4p变态网欧美系列| 亚洲图片在区色| 欧美超级乱淫片喷水| 欧洲亚洲女同hd| 欧美性xxxx极品高清hd直播| 日韩免费在线播放| 久久成人人人人精品欧| 亚洲国产私拍精品国模在线观看| 中文在线资源观看视频网站免费不卡| 欧美一级大片在线观看| 中文字幕免费精品一区| 日韩a**站在线观看| 国产精品一区二区三区成人| 亚洲自拍偷拍在线| 国产综合在线视频| 欧美人与性动交a欧美精品| 亚洲美女免费精品视频在线观看| 亚洲黄色在线看| 日韩av在线资源| 欧美日韩国产黄| 欧美成人免费小视频| 96sao精品视频在线观看| 欧美视频一区二区三区…| 色哟哟网站入口亚洲精品| 成人激情视频小说免费下载| 精品一区二区三区三区| 色哟哟入口国产精品| 欧美精品午夜视频| 国产精品电影网站| 亚洲国产日韩欧美在线动漫| 91在线免费看网站| 国产91ⅴ在线精品免费观看| 国产福利成人在线| 亚洲成年人在线播放| 亚洲精品日韩久久久| 97精品在线视频| 国产成人精品免费视频| 国产成人拍精品视频午夜网站| 国产精品一区专区欧美日韩| 国产视频综合在线| 亚洲偷欧美偷国内偷| 在线观看亚洲视频| 精品激情国产视频| 美女av一区二区三区| 在线日韩欧美视频| 国产精品啪视频| 中文字幕在线看视频国产欧美| 国内精久久久久久久久久人| 欧美一二三视频| 一区二区在线免费视频| 一夜七次郎国产精品亚洲| 欧美一乱一性一交一视频| 国内精品一区二区三区四区| www.色综合| 日韩美女视频免费看| 日韩av成人在线| 91在线高清视频| 色播久久人人爽人人爽人人片视av| 欧美精品电影免费在线观看| 热99精品只有里视频精品| 7777精品久久久久久| 亚洲激情在线视频| 国产噜噜噜噜久久久久久久久| 欧美精品精品精品精品免费| 日韩va亚洲va欧洲va国产| 欧美精品18videos性欧| 欧美肥老太性生活视频| 亚洲视频一区二区| 91av在线免费观看视频| 国产精品欧美久久久| 亚洲欧美日韩高清| 在线成人激情视频| 91黄色8090| 欧美精品在线观看91| 亚洲精品ady| 国产精品男人的天堂| 精品香蕉一区二区三区| 国内精品久久久久久久| 精品视频一区在线视频| 欧美激情一级欧美精品| 日韩高清a**址| 国产精品av在线播放| 日韩激情视频在线播放| 欧美情侣性视频| 国产午夜精品全部视频播放| 欧美视频在线看| 最近2019中文字幕第三页视频| 亚洲春色另类小说| 国产一区二区日韩| 一本色道久久88综合日韩精品| 川上优av一区二区线观看| 欧美激情中文字幕乱码免费| 国产精品亚洲视频在线观看| 国产一区二区黑人欧美xxxx| 欧美情侣性视频| 亚洲深夜福利在线| 97视频在线播放| 国产精品中文字幕在线观看| 26uuu亚洲国产精品| 亚洲福利在线视频| 精品视频9999| 91免费国产视频| 夜夜嗨av色一区二区不卡| 国产精品日韩精品| 欧美放荡办公室videos4k| 自拍偷拍亚洲欧美| 久久中文精品视频| 性欧美在线看片a免费观看|