【问题标题】:Converting malformed json array string to Java object将格式错误的 json 数组字符串转换为 Java 对象
【发布时间】:2018-11-04 11:31:46
【问题描述】:

我有一个格式错误的 json 数组字符串,我从 API 调用中获得如下:

[{\"ResponseCode\":1,\"ResponseMsg\":\"[{\"Code\":\"CA2305181\",\"Message\":\"Processed successfully\"}]\"}]

Response Msg 属性值中的方括号前有一个双引号。 有没有办法把它转换成 Java 对象?

到目前为止我已经尝试过: 我已经使用 Jackson 来解析它,但它给出了错误

ObjectMapper mapper = new ObjectMapper();
            mapper.setPropertyNamingStrategy(new ResponseNameStrategy());
            Response[] response = mapper.readValue(strOutput1, Response[].class);
Error: Can not deserialize instance of java.util.ArrayList out of VALUE_STRING token

我也尝试过使用 Gson 来解析它,但它也会报错

Gson gson = new GsonBuilder()
                    .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
                    .create();
            Response[] response = gson.fromJson(strOutput1, Response[].class);
Error: Expected BEGIN_ARRAY but was STRING at line 1 column 35 path $[0].ResponseMsg

我浏览了 StackOverflow 上的以下链接,但没有一个解决了我的问题:

How to Convert String Array JSON in a Java Object

Convert a JSON string to object in Java ME?

JSON Array to Java objects

Convert json String to array of Objects

converting 'malformed' java json object to javascript

【问题讨论】:

  • 我认为是时候回到那个 API 并弄清楚它为什么会发送损坏的 JSON。如果这是他们的错,那么没有人可以使用他们的服务。另一种选择是您可能在收到数据时对数据进行了处理。也许告诉我们你是如何得到这些损坏的 JSON 数据的。
  • 你的问题至少对我来说没有意义。当某些东西不是有效的 JSON 时,它不能被称为 JSON。它只是一个字符串。
  • 我得到这个 json 作为 Soap Web 服务响应的一部分,如下所示:[{"ResponseCode":1,"ResponseMsg":"[{\"Code\":\"CA2305181\ ",\"消息\":\"处理成功。\"}]"}]
  • 首先,服务应该立即修复。另外,我认为末尾还有一个额外的双引号 }]\"}]。那个双引号也是错误的吗?
  • 方括号前的双引号结束

标签: java json


【解决方案1】:

这就是我最终解决问题的方法:

String inputJsonStr = "[{\"ResponseCode\":1,\"ResponseMsg\":\"[{\"Code\":\"CA2305181\",\"Message\":\"Claim has been added successfully.\"}"
                + "]\"}]";
int indexOfRes = inputJsonStr.indexOf("ResponseMsg");

        if(inputJsonStr.substring(indexOfRes+13,indexOfRes+14).equals("\""))
        {
            inputJsonStr = inputJsonStr.substring(0,indexOfRes+13) + inputJsonStr.substring(indexOfRes+14);
        }
        int indexOfFirstClosingSquare = inputJsonStr.indexOf("]");
        if(inputJsonStr.substring(indexOfFirstClosingSquare+1, indexOfFirstClosingSquare+2).equals("\"")) {
            inputJsonStr = inputJsonStr.substring(0, indexOfFirstClosingSquare+1)+inputJsonStr.substring(indexOfFirstClosingSquare+2);
        }

现在inputJsonStr 包含一个有效的 json 数组,可以使用此 SO 链接中给出的 gson 轻松地将其解析为 Java 自定义对象数组:

Convert json String to array of Objects

【讨论】:

    【解决方案2】:

    正如我在评论中提到的,您应该准备好您的服务响应以解析它。

    我实现了一个例子:

    public class JsonTest {
        public static void main(String args[]) throws JsonProcessingException, IOException{
            String rawJson = 
                    "[{\"ResponseCode\":1,\"ResponseMsg\":\"[{\"Code\":\"CA2305181\",\"Message\":\"Processed successfully\"}]\"}]";
            String goodJson = "{"+rawJson.split("[{{.}]")[2]+"}";
            ObjectMapper mapper = new ObjectMapper();
            final ObjectNode node = mapper.readValue(goodJson, ObjectNode.class);
            System.out.println("Pretty Print: " + mapper.writerWithDefaultPrettyPrinter().writeValueAsString(node));
    
            System.out.println("Just code: " + node.get("Code"));   
        }
    
    }
    

    返回:

    【讨论】:

    • 在split方法中,字符类中的单头大括号也会达到同样的效果
    【解决方案3】:

    我认为答案在 cmets 中,您似乎试图在错误的地方解决问题。

    您正在接收想要解析为 java 对象的 json,不幸的是 json 格式错误,因此无法解析。

    作为一般规则,您永远不应该试图解决症状,而应该寻找根本原因并修复它,这听起来可能微不足道,但修复症状会导致系统混乱、不可预测和不可维护。

    所以答案是修复它被破坏的json。如果这是您可以控制的事情,那么在您等待修复时,您可以在解析 json 之前对其进行修复。

    这样您就不会影响您的解析,并且当第三方解决了问题时,只需删除一小部分字符串替换即可。但不要使用 hack,它只能在开发过程中使用。

    【讨论】:

    • 我无法控制 API 返回的内容。正如问题中提到的,我无法解析它。我什至尝试使用 JSONArray jsonArray = new JSONArray(strOutput1); 解析它仍然收到错误 Expected a ',' or '}' at 38 [character 39 line 1]
    猜你喜欢
    • 2012-05-20
    • 1970-01-01
    • 2019-04-28
    • 1970-01-01
    • 1970-01-01
    • 2013-08-29
    • 2011-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多