【问题标题】:Parse Kinesis data stream in AWS Lambda Java [closed]在 AWS Lambda Java 中解析 Kinesis 数据流 [关闭]
【发布时间】:2020-11-13 09:29:19
【问题描述】:

我正在用 Java 创建一个 AWS Lambda 函数来处理 Kinesis Data Stream。

我目前的解析设置包括:

  1. 按照 AWS 文档中的建议使用 UTF-8 进行字符串化
            for(KinesisEvent.KinesisEventRecord rec : event.getRecords())
            {
                String stringRecords = new String(rec.getKinesis().getData().array(), "UTF-8");

                    pageEventList.add(pageEvent);
            }
            
  1. 使用正则表达式模式清理字符
   a. non-ascii: "[^\\x00-\\x7F]";
   b. ascii-control-characters: "[\\p{Cntrl}&&[^\r\n\t]]";
   c. non-printable-characters: "\\p{C}";
  1. 格式化json字符串对象,不带方括号和逗号
        int firstBeginningCurlyBracketIndex = cleanString.indexOf("{");
        if (firstBeginningCurlyBracketIndex != -1 ){
            cleanString = cleanString.substring(firstBeginningCurlyBracketIndex + 1);
            cleanString = "[{" + cleanString;
        }

        int lastIndexOfCurlyBracketIndex = cleanString.lastIndexOf("}");
        if (lastIndexOfCurlyBracketIndex != -1) {
            cleanString = cleanString.substring(0, lastIndexOfCurlyBracketIndex);
            cleanString = cleanString + "}]";
        }

        cleanString = cleanString.replaceAll("}\\{", "\\},\\{");

目前,当我走到这一步时,我正在使用正则表达式解析将它们分离并解析为 JSON 对象。参考:How to match string within parentheses (nested) in Java?

        String REGEX_BRACKET_PATTERN_TWO_LAYERS = "(\\{(?:[^}{]+|\\{(?:[^}{]+|\\{[^}{]*\\})*\\})*\\})";

        Pattern splitDelRegex = Pattern.compile(REGEX_BRACKET_PATTERN_TWO_LAYERS);
        Matcher regexMatcher = splitDelRegex.matcher(nonAsciiRemovedString);
        List<String> matcherList = new ArrayList<String>();
        while (regexMatcher.find()) {
            String perm = regexMatcher.group(1);
            matcherList.add(perm);
        }

我尝试在第 3 步之后使用 Gson 和 Jackson 解析 string-json-array(参考:How to parse JSON in Java)。解析工作正常,直到数据流中出现随机无效的 JSON / 字符串并引发异常 - java.lang.Exception: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 2 column 1 path $

导致此异常的无效 json 如下所示:

[

 ...

  {
    "name": "banana"
    "description": "description"
  },
  {
    "name": "orange"
    "description": "description"
  }
GD~
{}
FDSE-}
]

我的问题是:

  1. 由于最后一个随机字符串部分非常随机,我很难将整个字符串格式化为有效的字符串 json 数组。如果有人有一个好主意来确保这个字符串 json 数组始终有效。

  2. 除了我在将 Kinesis Data Stream 解析为 Json 数据的步骤中描述的内容之外,顺便说一下,它正在使用 REGEX 虽然我仍然注意到最后的随机字符串,如果有人在这个解析过程中有经验,请分享与社区。我觉得关于 Lambda-Kinesis 这个主题的 AWS 文档不够详细,无法确保整个解析过程。

除此之外,我知道这可能只是因为来自数据流的数据质量。听听其他人在处理他们关于这个主题的数据方面的经验也很好。

【问题讨论】:

  • “如何解析 json...” - 不要手动,使用框架,不要重新发明轮子。杰克逊,gson,...
  • “因为字符串在字符串形式中没有被格式化为 json,所以目前使用 Gson 或 Jackson 会抛出异常。” - 你是什么意思?您的数据是否有效 json?如果是,框架将能够解析它。
  • 花括号在 JSON 字符串值中是合法的。请向我们展示您使用 Gson 或 Jackson 的代码,它无法解析上述字符串。
  • @Zabuzard 因此,在字符串 json 对象之前和之后都有非 ascii 字符和不可打印字符以及一些像 234 这样的随机数。所以,当我用 Gson 和 Jackson 运行整个字符串时,它抛出了异常。

标签: java json regex aws-lambda amazon-kinesis


【解决方案1】:

我尝试使用 Gson 库:

String jsonString = "{\"username\": \"apple2\", \"description\": \"this is an example{where problem is2}\" }";
    
GsonBuilder builder = new GsonBuilder();
Map<String,String> o = (Map<String, String>) builder.create().fromJson(jsonString, Object.class);
    
System.out.println("Map object : " + o);
System.out.println("UserName : " + o.get("username"));
System.out.println("Description : " + o.get("description"));

输出:

Map object : {username=apple2, description=this is an example{where problem is2}}
UserName : apple2
Description : this is an example{where problem is2}

【讨论】:

  • 感谢您的尝试!!我已经更新了这个问题,因为我正在处理的字符串还包含随机数和不可打印的字符。应该将其包含在原始问题中。很抱歉造成混乱
  • 随机数只在开头吗?您可以轻松提取数字并解析剩余的字符串。在这之间不是有效的 JSON。
  • 字符串以随机数开头,以随机字符串结尾。并且中间有 json 字符串。即 234454{ ... } { ... } { .... } { ... } { ... }]]H7
  • 目前正在尝试找出如何摆脱前面和结尾的那些
  • 当我更新我的问题时,json 字符串对象数组的清理部分被 Gson 库正确解析,但随机字符串弹出并抛出无效的 json 对象,从而导致异常。我将不得不考虑如何处理这个异常..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多