You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Avro RandomData生成含UNION类型的合法JSON样本?

如何用Avro RandomData生成带UNION类型标识的合法JSON样本?

问题背景

使用Avro v1.11.3版本的RandomData工具,基于以下User Schema生成随机JSON样本:

{
    "namespace": "example.avro",
    "type": "record",
    "name": "User",
    "fields": [
        {
            "name": "name",
            "type": "string"
        },
        {
            "name": "favorite_number",
            "type": ["int", "null"]
        },
        {
            "name": "favorite_color",
            "type": ["string", "null"]
        }
    ]
}

当前使用的Java代码如下:

package org.example;

import org.apache.avro.Schema;
import org.apache.avro.util.RandomData;

import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;

public class MyTest {
    public static void main(String [] args) throws IOException {
        MyTest me = new MyTest();
        ClassLoader classLoader = me.getClass().getClassLoader();
        InputStream is = classLoader.getResourceAsStream("person.avsc");
        Schema schema = new Schema.Parser().parse(is);
        Iterator<Object> it = new RandomData(schema, 1).iterator();
        System.out.println(it.next());
    }
}

执行后生成的JSON样本不符合Schema要求,UNION类型字段未生成带类型标识的结构:

{
    "name": "rymhxcnbcyohbtjmouegufvchxh",
    "favorite_number": 4211,
    "favorite_color": "red"
}

预期的合法JSON样本应为:

{
    "name": "rymhxcnbcyohbtjmouegufvchxh",
    "favorite_number": {
        "int": 4211
    },
    "favorite_color": {
        "string": "red"
    }
}

解决方案

RandomData生成的是Avro的GenericRecord实例,直接调用toString()输出的是简化格式,并非符合Avro JSON编码规范的序列化结果。需要使用Avro官方的JSON序列化工具类来处理,才能正确生成带UNION类型标识的结构。

修改后的代码如下:

package org.example;

import org.apache.avro.Schema;
import org.apache.avro.generic.GenericDatumWriter;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.io.DatumWriter;
import org.apache.avro.io.Encoder;
import org.apache.avro.io.JsonEncoder;
import org.apache.avro.util.RandomData;
import com.fasterxml.jackson.core.JsonFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.util.Iterator;

public class MyTest {
    public static void main(String [] args) throws IOException {
        MyTest me = new MyTest();
        ClassLoader classLoader = me.getClass().getClassLoader();
        InputStream is = classLoader.getResourceAsStream("person.avsc");
        Schema schema = new Schema.Parser().parse(is);
        
        // 生成随机GenericRecord
        Iterator<Object> it = new RandomData(schema, 1).iterator();
        GenericRecord record = (GenericRecord) it.next();
        
        // 使用Avro JsonEncoder序列化
        DatumWriter<GenericRecord> writer = new GenericDatumWriter<>(schema);
        JsonFactory jsonFactory = new JsonFactory();
        Encoder encoder = new JsonEncoder(schema, jsonFactory.createGenerator(new OutputStreamWriter(System.out)));
        writer.write(record, encoder);
        encoder.flush();
    }
}

说明

  1. 引入GenericDatumWriter和JsonEncoder类,这是Avro官方提供的JSON序列化工具,严格遵循Avro的JSON编码规则。
  2. 将RandomData生成的Object强制转换为GenericRecord(因为Schema是record类型,生成的实例必然是GenericRecord)。
  3. 通过JsonEncoder将GenericRecord序列化为符合规范的JSON,其中UNION类型字段会自动生成带类型标识的嵌套结构。

内容的提问来源于stack exchange,提问作者NoName

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 20:38:14