Jackson序列号Avro文件报错:com.fasterxml.jackson.databind.JsonMappingException: Not a union

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/u013771019/article/details/102659626

环境:

jdk 1.8

avro和jackson的maven依赖如下:

<dependency>
        <groupId>org.apache.avro</groupId>
        <artifactId>avro</artifactId>
        <version>1.7.4</version>
    </dependency>

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.4.0</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.4.1.3</version>
    </dependency>

avro的schema文件如下:

{"namespace": "idp.model",
 "type": "record",
 "name": "DtHourBasic",
 "fields": [
     {"name": "user_id", "type": "string"},
     {"name": "hour",  "type": "string"},
     {"name": "app_cat_id",  "type": "string"},
     {"name": "app_id",  "type": "string", "default": "null"},
     {"name": "lac", "type":["string", "null"], "default": "null"},
     {"name": "ci", "type":["string", "null"], "default": "null"},
     {"name": "city_code", "type":["string", "null"], "default": "null"},
     {"name": "frequency", "type": "int"},
     {"name": "max_time", "type": "string"},
     {"name": "min_time", "type": "string"},
     {"name": "c_city_code", "type": "string"}
 ]
}

报错如下:

运行代码:

public class JacksonUtils {

    private final static ObjectMapper mapper = new ObjectMapper();
    static {
        mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
        mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
    }

    /**
     * 将对象转换成json字符串,用于将发送的报文打印出到日志
     */
    public static String toString(Object object) {

        String result = null;
        if (null == object)
            return result;
        try {
            result = mapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            System.out.println("对象转换成json字符串出错");
            e.printStackTrace();
        }
        return result;
    }
}
DtHourBasic baseObj = DtHourBasic.newBuilder().setUserId("188xxx")
                .setAppCatId("01")
                .setAppId("07")
                .setLac("123")
                .setCi("123456")
                .setCCityCode("0512")
                .setHour("00")
                .setFrequency(3)
                .setMaxTime("201909090510")
                .setMinTime("201909090505")
                .setCityCode("510104")
                .build();

System.out.println(JacksonUtils.toString(result));

代码运行时,报错如下:

com.fasterxml.jackson.databind.JsonMappingException: Not a union: {"type":"record","name":"DtHourBasic","namespace":"idp.model","fields":[{"name":"user_id","type":"string"},{"name":"hour","type":"string"},{"name":"app_cat_id","type":"string"},{"name":"app_id","type":"string","default":"null"},{"name":"lac","type":["string","null"],"default":"null"},{"name":"ci","type":["string","null"],"default":"null"},{"name":"city_code","type":["string","null"],"default":"null"},{"name":"frequency","type":"int"},{"name":"max_time","type":"string"},{"name":"min_time","type":"string"},{"name":"c_city_code","type":"string"}]} (through reference chain: idp.model.DtHourBasic["schema"]->org.apache.avro.RecordSchema["types"])
	at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:232)
	at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:197)
	at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:187)
	at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:647)
	at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
	at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:505)
	at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:639)
	at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:152)
	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:114)
	at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:2866)
	at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:2323)
	at com.dmp.utils.JacksonUtils.toString(JacksonUtils.java:33)
	at com.dmp.TestHourProcess.testMergeBasicInfo(TestHourProcess.java:39)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.apache.avro.AvroRuntimeException: Not a union: {"type":"record","name":"DtHourBasic","namespace":"idp.model","fields":[{"name":"user_id","type":"string"},{"name":"hour","type":"string"},{"name":"app_cat_id","type":"string"},{"name":"app_id","type":"string","default":"null"},{"name":"lac","type":["string","null"],"default":"null"},{"name":"ci","type":["string","null"],"default":"null"},{"name":"city_code","type":["string","null"],"default":"null"},{"name":"frequency","type":"int"},{"name":"max_time","type":"string"},{"name":"min_time","type":"string"},{"name":"c_city_code","type":"string"}]}
	at org.apache.avro.Schema.getTypes(Schema.java:266)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:466)
	at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:639)
	... 31 more

发现Jackson在序列化avro文件的时候,也会去序列号Schema中的属性,在网上找到了一篇blog,

参考地址为:https://www.jb51.net/article/149947.htm

尝试搞了一下,虽然不报错了,但是序列化后的json字符串中有些属性时重复的,头大!!!

{
    "user_id":"188xxx",
    "hour":"00",
    "app_cat_id":"01",
    "app_id":"07",
    "lac":"123",
    "ci":"123456",
    "city_code":"510104",
    "frequency":6,
    "max_time":"201909090511",
    "min_time":"201909090506",
    "c_city_code":"0512",
    "userId":"188xxx",
    "appCatId":"01",
    "appId":"07",
    "ccityCode":"0512",
    "maxTime":"201909090511",
    "minTime":"201909090506",
    "cityCode":"510104"
}

最后,发现Avro类自带的toString方法就可以直接序列化。。。

好吧,干了半天。。。

public abstract class SpecificRecordBase
  implements SpecificRecord, Comparable<SpecificRecord>, GenericRecord {
...
@Override
  public String toString() {
    return SpecificData.get().toString(this);
  }
}

原生的API要多尝试啊。。。

猜你喜欢

转载自blog.csdn.net/u013771019/article/details/102659626
今日推荐