前言
本文准确来讲是探讨如何用 jackson 来序列化 apache avro 对象,因为简单用 jackson 来序列化 apache avro 对象会报错。原因是序列化 schema getschema() 时会报错,后面会讲到,需要序列化时忽略该属性。那么能不能在 getschema() 上加上 @jsonignore 来忽略该属性呢?原理上是通的。不过手工修改的 avsc 生成的 java 文件随时会因为重新编译而还原,所以不太具有实际可操作性,当然通过定制编译 avsc 用的模板文件来加入 @jsonignore 是另一回事。
由于不能在要忽略的字段上添加 jsonignore 来控制,而如果我们明确了要忽略的字段类型的话,是能够定制 jackson 的 objectmapper 来屏蔽某个特定的类型。来看下面序列化 apache avro 对象的例子:
假设我们有一个 apache 的 schema 文件 user.avsc, 内容如下:
?
1 2 3 4 5 6 7 8 9 |
|
编译用 avro-tools compile schema user.avsc . 生成 cc.unmi.data.user.java 源文件,当我们试图对类型的对象用 jackson 进行序列化时
?
1 2 3 |
|
收到异常(关键信息)
从上面的错误可以定位到 jackson 的试图序列化 user 对象的
?
1 |
|
而 org.apache.avro.schema 中的 getvaluetype() 直接抛出异常拒绝被归化
?
1 2 3 |
|
因此,要实现序列化 apache avro 对象,解决的办法有三
- 凡是 org.apache.avro.schema 的属性不被序列化(schema 输出确实用处不大)
- 或对于org.apache.avro.schema 类型的属性定制序列化,比如输出为完整类名,或 schema 定义的文本内容
- 再来一个,对 specificrecordbase 类型的 schema 名称的属性进行忽略(avro 类型继承自 specificrecordbase)
它们的实现分别如下
忽略序列化指定类型的属性
先定义一个标注了 @jsonignoretype 的注解
?
1 2 3 |
|
序列化 apache avro 对象前给 objectmapp 加一个 mixin
?
1 2 3 4 5 |
|
有了上面高度行的代码,这儿的 apache avro user 对象就能被正常序列化了,输出为
这样 getschema() 返回的类型,或另何对象中有 org.apache.avro.schema 类型的属性都会在序列化时忽略掉
定制 schema 属的输出内容
对于 schema 类型的属性,除了前面采取堵的方式,还可以因利疏导,即定制 schema 属性值的输出内容
定制化 schema 序列化方式
?
1 2 3 4 5 6 7 |
|
给 objectmapper 加上定制的序列化器
?
1 2 3 4 5 6 7 |
|
序列化后产生的输出如下
如果在 avroschemaserializer 把 jgen.writestring(value.getfullname()) 替换如下
?
1 |
|
并且序列化后对内容进行格式化输出
?
1 2 3 4 5 6 |
|
指定特定对象的属性名进行过滤
从语义上除了 ignore 外,filter 也像是干这事的,可以尝试过下面的方式, 分两步走
定义一个带 @jsonfilter 的注解,也是不显示注解到任何类
?
1 2 |
|
给 objectmapper 设置 filter
?
1 2 3 4 5 6 7 8 |
|
输出效果没有意外,也能避免序列化 schema 属性
这最后一种方式是本篇写作行将结束时找到并验证的,所以不写出来,不进行梳理可能永远只会第一种方法。
链接:
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。
原文链接:https://yanbin.blog/jackson-ignore-specified-field-type/
本文链接:https://my.lmcjl.com/post/9136.html
4 评论