如何使用可空字段将avro模式的JSON消息转换为有效JSON?

时间:2019-05-14 15:41:41

标签: java json regex avro

我想使用avro模式将JSON消息发送到kafka主题。

平均模式允许多种类型:

{  
   "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元素。我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

我可以将typeA转换为:

"typeA":{
    "int":12345
},

但是typeBtypeC对我来说太困难了,因为我无法精确匹配。当我尝试用数组替换typeB时,不知何故。另一个地方也被替换了,这是我们不想要的。

如果您或其他人可以解决该问题,那么typeC也可以轻松解决。因为typeBtypeC是相似的。我也很好奇解决方案。让我知道!

我现在将分享如何修复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
},

答案 1 :(得分:0)

由于所有值的名称,这并不是超级有趣,但是Jackson很好用。

我将您想要的json粘贴到json2pojo中:

{
  "typeA":{
     "int":12345
  },
  "typeB":{
     "array":[
        {
           "feature":1,
           "value":"1"
        },
        {
           "feature":2,
           "value":"2"
        }
     ]
  },
  "typeC":{
     "array":[
        {
           "a":12345,
           "data":[
              {
                 "a":12345,
                 "b":[
                    12345,
                    12345,
                    12345
                 ]
              }
           ]
        }
     ]
  }
}

使用zip下载功能将这些类下载到我的本地开发环境中。

然后创建了这个类的怪异性,该类使用json2pojo生成的类来测试Jackson。

public class JacksonSerialization {

   public static void main(String... args) throws Exception {

       TypeA typeA = new TypeA();
       typeA.setInt(12345);

       TypeB typeB = new TypeB();
       ArrayList<Array> arrays = new ArrayList<>();
       arrays.add(createArray(1, "1"));
       arrays.add(createArray(2, "2"));
       typeB.setArray(arrays);

       TypeC typeC = new TypeC();

       ArrayList<Integer> integers = new ArrayList<>();
       integers.add(12345);
       integers.add(12345);
       integers.add(12345);

       ArrayList<Datum> data = new ArrayList<>();
       Datum datum = new Datum();
       datum.setA(12345);
       datum.setB(integers);
       data.add(datum);

       Array_ array_ = new Array_();
       array_.setA(12345);
       array_.setData(data);

       ArrayList<Array_> array_s = new ArrayList<>();
       array_s.add(array_);
       typeC.setArray(array_s);

       Example example = new Example();
       example.setTypeA(typeA);
       example.setTypeB(typeB);
       example.setTypeC(typeC);

       ObjectMapper mapper = new ObjectMapper();
       mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, false);
       mapper.configure(SerializationFeature.INDENT_OUTPUT, true);

       ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
       //mapper.writeValue(byteArrayOutputStream, example);
       mapper.writeValue(new File("target/Example.json"), example);

       String json = byteArrayOutputStream.toString();

       json = StringEscapeUtils.escapeCsv(json);

       System.out.println(json);
   }

   private static Array createArray(Integer feature, String value) {

       Array array = new Array();
       array.setFeature(feature);
       array.setValue(value);

       return array;
   }
}

运行此类时,将生成以下json。

{
  "typeA" : {
    "int" : 123456
  },
  "typeB" : {
    "array" : [ {
      "feature" : 1,
      "value" : "1"
    }, {
      "feature" : 2,
      "value" : "2"
    } ]
  },
  "typeC" : {
    "array" : [ {
      "a" : 12345,
      "data" : [ {
        "a" : 12345,
        "b" : [ 12345, 12345, 12345 ]
      } ]
    } ]
  }
}

我认为这与您的要求非常接近。