0

我们有一些代码,我们将一个 JSON 文件读入一个字符串,然后使用Json-lib它来处理它,如下所示:

// ...
JSONObject jsonObj = (JSONObject) JSONSerializer.toJSON(jsonStr);
// ...

我们现在有一个文件实际上是一个 JSONArray 的情况(即以 开头[和结尾])。该文件通过了所有 JSON 验证测试,但我们的代码引发了以下异常:

java.lang.ClassCastException: net.sf.json.JSONArray cannot be cast to net.sf.json.JSONObject

我们可以通过以下 hack 来解决这个问题:

// ...
JSONObject jsonObj = (JSONObject) JSONSerializer.toJSON("{" + jsonStr + "}");
// ...

问题:有没有一种方法来处理文件,而不诉诸黑客?

4

2 回答 2

1

问题:有没有一种方法来处理文件,而不诉诸黑客?

我假设您正在使用标签所暗示的JSON-lib 。[json-lib]

我还假设您在为代码编写单元测试时遇到了这个问题。(如果不是……为什么不呢?)

在 JSON-lib API 中,JSONObject并且JSONArray有一个共同的 supertype JSON,所以你应该能够将一个JSONObjector分配给一个JSONArraytype 的变量JSON。(该JSON接口具有方法isObjectisArray允许您测试 aJSON是对象还是数组......但不是asObjectorasArray方法。)

但是,如果您的测试确实需要JSONObject...,那么您就有问题了。在 JSON 中,“对象”和“数组”数据结构是根本不同的。两者都不是另一个的概念子类型。您的“黑客”正在做的是将 JSON 数组包装在 JSON 对象中。这可能是也可能不是正确的做法。(我怀疑不是。但如果这是正确的做法,那么“hack”是一种合理的方法。您也可以构造 a并以编程JSONObject方式将解析后的内容添加到其中。)JSONArray

如果被测代码被设计/指定为使用 JSON 对象而不是 JSON 数组,那么正确的解决方案是在某些时候将输入文件作为错误输入拒绝。

  • 如果您的测试代码旨在进行解析,那么它应该抛出异常(或其他)以拒绝错误的输入文件。您的单元测试应该检查它是否这样做。

  • 如果您的被测代码设计为采用 (parsed) JSONObject,则测试用例(包含 JSON 数组的输入文件)是一个错误的测试用例。删除它...出于本单元测试的目的。


简而言之,您的问题的正确解决方案将取决于您要测试的代码应该做什么

于 2022-01-09T04:32:05.157 回答
0

您可以将 jsonStr 读取为 JSON 对象,然后将其转换为 Java 对象:

    net.sf.json.JSON json = JSONSerializer.toJSON(jsonStr);
    YourJavaObject jObj = null;
    List<YourJavaObject> list  = null;
    if(json instanceof JSONObject){
        jObj = (YourJavaObject)JSONObject.toBean(JSONObject.fromObject(json), YourJavaObject.class);
    }else if(json instanceof JSONArray){
        list = JSONArray.toList(JSONArray.fromObject(json), new YourJavaObject(), new JsonConfig());
    }
于 2022-01-09T00:45:31.610 回答