【问题标题】:Class cast Exception during JSON ParsingJSON解析期间的类转换异常
【发布时间】:2020-06-25 03:03:17
【问题描述】:

我一直在尝试解析这个字符串以获取 Target-key

的值
{
  "Type" : "Notification",
  "MessageId" : "something",
  "Message" : "{\"buildId\":\"something\",\"somekey\":\"somevalue\",\"startTimeMillis\":1592526605121,\"table\":{\"key1\":\"val1\",\"tableName\":\"some table\",\"tableprop\":{\"bucketCount\":123,\"bucketColumns\":[\"X\",\"Y\"]},\"tableSortProperty\":{\"sortColumns\":[\"X\",\"Y\"]}},\"createStatementLocation\":{\"s3Bucket\":\"somebucket\",\"s3Prefix\":\"someprefix\"},\"Target-key\":\"Target-Value\"}",
  "Timestamp" : "2020-06-19T19:23:46.378Z"
}

我尝试了以下方法:

message.getBody() 返回 Json 字符串。这里的 message 是 SQS Message 对象

方法一:


JSONObject jsonObject = new JSONObject(message.getBody());
JSONObject obj = (JSONObject) jsonObject.get("Message");
String res = (String)obj.get("Target-key");

我在上面代码的第 2 行收到错误

java.lang.String cannot be cast to org.json.JSONObject: java.lang.ClassCastException
java.lang.ClassCastException: java.lang.String cannot be cast to org.json.JSONObject

方法 2: 使用 Jackson 还会再次在 line2 上产生类转换异常。

Map<String,Map<String,String> > mymap;
mymap = objectMapper.readValue(message.getBody(), Map.class);
Map<String, String> mymap2 = mymap.get("Message");
String res = mymap2.get("Target-key");

方法 3: 也尝试使用杰克逊树节点

但是,下面的解决方案似乎确实有效,但我想知道为什么上面的方法失败了

Map<String,String> messageMap;
messageMap = objectMapper.readValue(message.getBody(), Map.class);
Map<String,String> mmap = objectMapper.readValue(messageMap.get("Message"), Map.class);
String res = mmap.get("Target-key");

PS:我已经尝试了许多关于堆栈溢出的替代方案和类似的问题,但这对我的情况没有帮助。

实际的key和value已经被some-key和some-value替换了。

编辑: 我偷偷进入源数据并更新了 JSON

【问题讨论】:

  • 您的输入是否可能有引号?看起来您的原始输入可能不是您所期望的。
  • 消息为 JSON {"key":"value"} 类型。消息是此大括号中的键之一。外部大括号不是括在 AWS SQS 控制台中的引号。我正在使用 message.getBody() ,其中消息是 SQS 定义的对象。它的返回类型是字符串。
  • 你可能是对的。我偷偷进入源发现消息是这样的“消息”:“{\“buildId\”:\“B-2020.06.19.00.A........直到结束,封闭和分隔。这不是 JSON。任何线索。如何解析这个? @Deadron
  • 更新了 JSON

标签: java json jackson


【解决方案1】:

现在我们可以看到原始来源,您的问题很明显。 Message 的值是字符串而不是嵌套对象。

JSONObject jsonObject = new JSONObject(message.getBody());
JSONObject obj= new JSONObject(jsonObject.getString("Message"));

【讨论】:

  • 是的,以前无法访问输入。输入后就很明显了。我没想到这个输入tbh。谢谢你提醒我检查。赞成,接受
【解决方案2】:

在您的 json 中存在解析错误 “bucketCount”:XYZ,

XYZ 可能会出现在“XYZ”之类的引号内。 你可以在http://json2table.com查看你的json

【讨论】:

  • XYZ 是某个整数值。这就是为什么它没有用引号括起来
【解决方案3】:

它失败是因为解析的结果不是字符串,也不是 Map,甚至不是 Map>。结果对象的结构更复杂。

如果您需要在您的应用程序中拥有该对象以供进一步使用,您可以创建一个类来存储,Jackson 会将其反序列化为对象。

如果您不需要整个对象,Jackson 库中有 readTree 方法。

它将创建 JsonNode 对象,您可以使用标签名称进行导航。类似的东西

res.get("Message").get("Target-key")

(考虑格式正确的输入 JSON)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 2020-09-18
    • 2013-11-06
    • 2023-03-05
    • 1970-01-01
    相关资源
    最近更新 更多