我有来自 API 的 JSON 响应,我想根据现有的 Avro 架构进行验证(对名称和类型进行严格验证)。
响应类型为
{"姓名":"亚历克斯","年龄":23,"性别":"男","活跃":"真"}
模式具有上述类型和数据类型,我想验证模式并在失败时抛出异常。(最好是 JAVA)。
我已经阅读了使用命令行的解决方案,但我想以编程方式完成它。
提前致谢
<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;
}
}
}
注意:如果您在 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();
我们在 C# 中有类似的东西吗?我想验证通过 API 接收的 JSON 消息并根据架构验证它,但 .NET C# 中没有可用的选项