如何根据 Avro 架构验证 JSON

问题描述 投票:0回答:3

我有来自 API 的 JSON 响应,我想根据现有的 Avro 架构进行验证(对名称和类型进行严格验证)。

响应类型为

{"姓名":"亚历克斯","年龄":23,"性别":"男","活跃":"真"}

模式具有上述类型和数据类型,我想验证模式并在失败时抛出异常。(最好是 JAVA)。

我已经阅读了使用命令行的解决方案,但我想以编程方式完成它。

提前致谢

java json validation schema avro
3个回答
12
投票

添加 Avro 依赖项

        <dependency>
            <groupId>org.apache.avro</groupId>
            <artifactId>avro</artifactId>
            <version>${version}</version>
        </dependency>

编程验证

这是您可以通过编程方式验证它的方法。

import org.apache.avro.AvroTypeException;
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericDatumReader;
import org.apache.avro.io.DatumReader;
import org.apache.avro.io.Decoder;
import org.apache.avro.io.DecoderFactory;

import java.io.*;

public class MainClass {
    public static void main (String [] args) throws Exception {
        Schema schema = new Schema.Parser().parse("{\n" +
                "     \"type\": \"record\",\n" +
                "     \"namespace\": \"com.acme\",\n" +
                "     \"name\": \"Test\",\n" +
                "     \"fields\": [\n" +
                "       { \"name\": \"name\", \"type\": \"string\" },\n" +
                "       { \"name\": \"age\", \"type\": \"int\" },\n" +
                "       { \"name\": \"sex\", \"type\": \"string\" },\n" +
                "       { \"name\": \"active\", \"type\": \"boolean\" }\n" +
                "     ]\n" +
                "}");
        String json = "{\"name\":\"alex\",\"age\":23,\"sex\":\"M\",\"active\":true}";
        System.out.println(validateJson(json, schema));
        String invalidJson = "{\"name\":\"alex\",\"age\":23,\"sex\":\"M\"}"; // missing active field
        System.out.println(validateJson(invalidJson, schema));
    }

    public static boolean validateJson(String json, Schema schema) throws Exception {
        InputStream input = new ByteArrayInputStream(json.getBytes());
        DataInputStream din = new DataInputStream(input);

        try {
            DatumReader reader = new GenericDatumReader(schema);
            Decoder decoder = DecoderFactory.get().jsonDecoder(schema, din);
            reader.read(null, decoder);
            return true;
        } catch (AvroTypeException e) {
            System.out.println(e.getMessage());
            return false;
        }
    }
}

0
投票

注意:如果您在 java 项目中并在验证 json 时遇到上述错误。

在我们的项目中,我们期望一个非常长的 JSON 对象,具有多个可选字段,因此很难找到它失败的地方。

使用 SpecificDatumReader/GenericDatumReaders 和其他可能的方法尝试了不同的方法,但我总是以 Expected start-union 结束。已获取 VALUE_STRING

我们有一个 SpringBoot 应用程序,并且我们已经将 avsc 文件转换为 Java。所以我们的想法是,如果我们能够填充 Class 对象并能够成功序列化它,则表明收到的 JSON 是有效的。

因此我们最终使用基本的 ObjectMapper 来填充该类。如果您使用 avro 库将 avsc 文件编译为 Java,那么它会附带一些默认方法来对类进行编码/解码

ObjectMapper mapper = new ObjectMapper();
// DeSerializing the JSON to Avro class, but this doesn't check for Schema restrictions
StatusUpdated obj = mapper.readValue(payload, StatusUpdated.class);
// Encoding the class and serializing to raw format, this step validates based on schema
obj.toByteBuffer();

0
投票

我们在 C# 中有类似的东西吗?我想验证通过 API 接收的 JSON 消息并根据架构验证它,但 .NET C# 中没有可用的选项

© www.soinside.com 2019 - 2024. All rights reserved.