Jee*_*eef 2 java jackson avro kotlin
我在编组/解组avro生成的类时遇到了一个奇怪的问题。我得到的错误是抛出一个不是枚举错误 - 除了我的类中没有任何枚举。
错误具体是这样的:
com.fasterxml.jackson.databind.JsonMappingException:不是枚举:{"type":"record","name":"TimeUpdateTopic","namespace":"org.company.mmd.time","fields":[ {"name":"time","type":"double"}]}(通过参考链:org.company.mmd.time.TimeUpdateTopic["schema"]->org.apache.avro.Schema$RecordSchema[ "enumDefault"])
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import org.junit.Test
class TimeUpdateTopicTest {
val objectMapper = ObjectMapper().registerModule(JavaTimeModule())
@Test
fun decode() {
val t = TimeUpdateTopic(1.0)
objectMapper.writeValueAsString(t)
}
}
Run Code Online (Sandbox Code Playgroud)
@namespace("org.company.mmd.time")
protocol TimeMonitor {
record TimeUpdateTopic {
double time;
}
}
Run Code Online (Sandbox Code Playgroud)
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import org.junit.Test
class TimeUpdateTopicTest {
val objectMapper = ObjectMapper().registerModule(JavaTimeModule())
@Test
fun decode() {
val t = TimeUpdateTopic(1.0)
objectMapper.writeValueAsString(t)
}
}
Run Code Online (Sandbox Code Playgroud)
我在这里做一些愚蠢和/或错误的事情吗?或者这是一个实际的错误
我可以使用此函数获取 JSON:
inline fun <reified T: SpecificRecordBase> StringFromAvroGenerated(obj: T) : String {
val schema = obj.schema
val writer = SpecificDatumWriter(T::class.java)
val stream = ByteArrayOutputStream()
var jsonEncoder = EncoderFactory.get().jsonEncoder(schema, stream)
writer.write(obj, jsonEncoder)
jsonEncoder.flush()
return stream.toString("UTF-8")
}
Run Code Online (Sandbox Code Playgroud)
但我假设这应该是杰克逊自动的
所以看起来有两种方法可以解决我的问题(感谢JsonMappingException 在将 avro 生成的对象序列化为 json 时)
所以第一个选项要求我创建一个像这样的 Mixin:
abstract class AvroMixIn {
@JsonIgnore
abstract fun getSchema(): org.apache.avro.Schema
@JsonIgnore
abstract fun getSpecificData() : org.apache.avro.specific.SpecificData
}
Run Code Online (Sandbox Code Playgroud)
然后当我制作对象映射器时:
val objectMapper = ObjectMapper()
.registerModule(JavaTimeModule())
.addMixIn(Object::class.java, AvroMixIn::class.java)
Run Code Online (Sandbox Code Playgroud)
我选择Object::class.java而不是实际的类,因为它应该适用于所有类。可能更好的解决方案是将其应用于所有 AvroGenerated 的共享基类。
这实际上是我采取的第一种方法,因为它看起来更“无情”。
1) 检查 avro 项目 2) 将enum.vm, fixed.vm, protocol.vm,复制record.vm到/avro_templates我的项目主根目录之外的目录中 3) 将@com.fasterxml.jackson.annotation.JsonIgnore属性添加到模板中:
#end
@com.fasterxml.jackson.annotation.JsonIgnore
public org.apache.avro.specific.SpecificData getSpecificData() { return MODEL$; }
@com.fasterxml.jackson.annotation.JsonIgnore
public org.apache.avro.Schema getSchema() { return SCHEMA$; }
// Used by DatumWriter. Applications should not call.
Run Code Online (Sandbox Code Playgroud)
4)更新gradle任务:
avro {
dateTimeLogicalType="JSR310"
templateDirectory = "avro_templates/"
}
Run Code Online (Sandbox Code Playgroud)
5)重新构建avro类
(现在一切正常)
| 归档时间: |
|
| 查看次数: |
3056 次 |
| 最近记录: |