无法解析JSON属性“null”

时间:2011-07-14 00:31:14

标签: java json json-lib

我在尝试解析JSON“null”属性时遇到了一个麻烦,请帮助我理解真正的问题是什么。我有一个以下JSON:

{
  "properties" : {        
    "null" : {
      "value" : false
    }
  }
}

我使用http://jsonlint.com来验证此JSON是否有效。我试图从java解析它:

import net.sf.json.JSONObject;
import java.io.IOException;

public class Test {
    public static void main(String[] args) throws IOException {
        String st = "{" +
                "      'properties' : {" +
                "        'null' : {" +
                "          'value' : false" +
                "        }" +
                "      }" +
                "}";
        JSONObject.fromObject(st);
    }
}

但得到例外:

Exception in thread "main" java.lang.ClassCastException: JSON keys must be strings.
    at net.sf.json.JSONObject._fromJSONObject(JSONObject.java:927)
    at net.sf.json.JSONObject.fromObject(JSONObject.java:155)
    at net.sf.json.JSONSerializer.toJSON(JSONSerializer.java:108)
    at net.sf.json.AbstractJSON._processValue(AbstractJSON.java:238)
    at net.sf.json.JSONObject._processValue(JSONObject.java:2655)
    at net.sf.json.JSONObject.processValue(JSONObject.java:2721)
    at net.sf.json.JSONObject.element(JSONObject.java:1786)
    at net.sf.json.JSONObject._fromJSONTokener(JSONObject.java:1036)
    at net.sf.json.JSONObject._fromString(JSONObject.java:1201)
    at net.sf.json.JSONObject.fromObject(JSONObject.java:165)
    at net.sf.json.JSONObject.fromObject(JSONObject.java:134)

我使用http://json-lib.sourceforge.net的json-lib-2.4-jdk15.jar来解析它。有人可以澄清一下吗?为什么这个库抛出异常,但在线验证器说它是有效的JSON?这是库中的一个错误,或者我做错了什么?

4 个答案:

答案 0 :(得分:3)

JSON-lib最初使用输入JSON解析并填充Java Map。不幸的是,JSON-lib然后检查每个JSON对象元素名称是否是JSON nullnull检查是在JSONNull.equals(Object)方法中执行的。对于“null”JSON字符串,此方法返回true,当然这实际上不是JSON null值。

我建议为此问题提交JSON-lib项目的错误。 JSONNull.equals(Object)的实施存在缺陷。

不幸的是,使用自定义PropertyNameProcessor无法处理此问题。

可用于更直接解决方案的选项包括自己更改JSON-lib代码或切换库。

如果您可以切换库,我强烈推荐Jackson。以下是使用它在原始问题中反序列化示例JSON的示例。

/*
{
  "properties" : {        
    "null" : {
      "value" : false
    }
  }
}
 */
String json = "{\"properties\":{\"null\":{\"value\":false}}}";

ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map = mapper.readValue(json, Map.class);
System.out.println(map);
// output: {properties={null={value=false}}}

Map<String, Object> propertiesMap = (Map) map.get("properties");
System.out.println(propertiesMap);
// output: {null={value=false}}

Map<String, Object> nullMap = (Map) propertiesMap.get("null");
System.out.println(nullMap);
// output: {value=false}

答案 1 :(得分:2)

发布的第一个JSON是有效的JSON:但是,Java中的JSON无效 - 只有"对[required]键引用有效。来自json.org

  
    

字符串是零个或多个Unicode字符的序列,用双引号包装,使用反斜杠转义....

  

但是,这听起来像一个bug,假设它不是由无效的 JSON触发它(库可以用无效的JSON做任何想做的事)。 ..如果这确实是一个“错误”,我们必须看看源(或错误报告/用户体验)才能最终说出来。我在下面添加了一些可供尝试的建议,可能会显示预期的行为或更详细地概述原因/问题。

考虑这个最小的测试用例(使用有效的JSON):

String st = "{ \"null\": \"hello world!\" }";

这可能会带来更多亮点,具体取决于提取时第一项是"null"还是null

String st = "[ \"null\" ]";

快乐的编码。

答案 2 :(得分:0)

gson库链接是:

http://code.google.com/p/google-gson/

我通常使用gson来生成josn字符串,所以我找到了一些其他人在stackoverflow中发布用gson解析json字符串的示例,请参阅链接:

Converting JSON to Java

答案 3 :(得分:-1)

建议你使用Gson,

使用java Map和List构造json字符串, 然后使用Gson输出Map或List对象