我想使用 avro-schema 向 kafka 主题发送一条 JSON 消息。
avro 模式允许多种类型:
{
"name":"typeA",
"type":[
"int",
"null"
],
"default":null
}
如果该值为 null,则一切正常。如果类型是 int
(如本例所示),则必须显式指定。查看此票AVRO-1582 .
我有这个 JSON:
{
"typeA":12345,
"typeB":[
{
"feature":1,
"value":"1"
},
{
"feature":2,
"value":"2"
}
],
"typeC":[
{
"a":12345,
"data":[
{
"a":12345,
"b":[
12345,
12345,
12345
]
}
]
}
]
}
我想转换成这个 JSON:
{
"typeA":{
"int":12345
},
"typeB":{
"array":[
{
"feature":1,
"value":"1"
},
{
"feature":2,
"value":"2"
}
]
},
"typeC":{
"array":[
{
"a":12345,
"data":[
{
"a":12345,
"b":[
12345,
12345,
12345
]
}
]
}
]
}
}
是否可以将 "typeA":12345
转换为 "typeA":{"int":12345}
?有一个简单的方法来处理这个问题吗?
我知道每个字段的类型,因此我可以在 JAVA 中使用正则表达式:
json.replaceAll("typeA\":([^,]*),\"", "typeA\":{\"int\":$1},\"");
处理数组或最后一个 JSON 元素很困难。我该如何解决这个问题?
最佳答案
我可以将 typeA
转换为:
"typeA":{
"int":12345
},
但是typeB
和typeC
对我来说太难了,因为我无法精确匹配。不知何故,当我尝试用数组替换 typeB
时。另一个地方也被替换了,这是我们不希望的。
如果您或其他人可以解决该问题,那么 typeC
也可以轻松修复。因为typeB
和typeC
是相似的。我也很好奇解决方案是什么。所以请告诉我!
我现在将分享我如何修复typeA
。这是Java代码:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
public static void main(String[] args) {
String line = "{\r\n" +
" \"typeA\":12345,\r\n" +
" \"typeB\":[\r\n" +
" {\r\n" +
" \"feature\":1,\r\n" +
" \"value\":\"1\"\r\n" +
" },\r\n" +
" {\r\n" +
" \"feature\":2,\r\n" +
" \"value\":\"2\"\r\n" +
" }\r\n" +
" ],\r\n" +
" \"typeC\":[\r\n" +
" {\r\n" +
" \"a\":12345,\r\n" +
" \"data\":[\r\n" +
" {\r\n" +
" \"a\":12345,\r\n" +
" \"b\":[\r\n" +
" 12345,\r\n" +
" 12345,\r\n" +
" 12345\r\n" +
" ]\r\n" +
" }\r\n" +
" ]\r\n" +
" }\r\n" +
" ]\r\n" +
"}";
String regex = "(\\\"type[A-Z]\\\"):(\\d*)|(\\[.*)|(.*\\])";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
if(matcher.group().equals("\"typeA\":12345")) {
String regex2 = "(\\\"typeA\\\"):(\\d*)";
line = line.replaceAll(regex2, "$1:{\"int\":$2}");
}
if(matcher.group().equals("\"typeB\":") ) {
//I couldn't finish this typeB, because it's too difficult
// String regex3 = "(\\\"type[B]\\\"):|(\\s{3}],)";
// line = line.replaceAll(regex3, "$1 :{ array: $2 ");
}
}
System.out.println("line: " + line);
}
}
首先我使用了这个正则表达式(\"type[A-Z]\"):(\d*)|(\[.*)|(.*\])
。该正则表达式为我们提供了几个我们想要查看的组。
最终 while 循环遇到 "typeA":12345
这就是我们使用正则表达式 ("typeA"):(\d*)
的地方。我们使用该正则表达式将 typeA
转换为:
"typeA":{
"int":12345
},
关于java - 如何将 JSON 消息转换为具有可为空字段的 avro 模式的有效 JSON?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56134167/