2011-07-14 174 views
3

我试图解析JSON“null”属性时遇到了一个麻烦,请帮我理解真正的问题。我有一个以下的JSON:无法解析JSON属性“null”

{ 
    "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) 

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

+0

这不是问题的原因,但'null'是在JavaScript中的关键字。你真的需要使用它作为你的财产的名称? – aroth

+0

@aroth 1)JSON不是JavaScript--它是JavaScript文字的形式化子集,其中对象关键字需要用双引号括起来2)'“null”不是'null' – 2011-07-14 00:41:38

+0

@pst - JSON不是JavaScript,但通常你最终会在JavaScript中使用它(不是说这不能在JavaScript中工作,但它肯定会造成一些[令人困惑的代码](http://jsfiddle.net/SZSm6/))。而'null'也是Java中的一个关键字。那个''null''不是'null'是不重要的。在我看来,它在语义上仍然含糊地称为“null”属性。 – aroth

回答

2

第一个JSON贴是有效的JSON:JSON的在Java,但是,是不是有效的 - 只有"是有效的[必需]键报价。从json.org

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

然而,这听起来像一个bug,假设它不是由无效 JSON输送到它(库可以为所欲为无效JSON)......一个人必须要看看源触发(或错误报告/用户体验)可以肯定地说,如果这确实是一个“错误”。我在下面添加了一些建议,可以显示预期的行为或详细说明原因/问题。

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

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

这还可以棚更多的光,这取决于是否提取时的第一项是"null"null

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

快乐的编码。

-1

建议您使用GSON,

和使用Java地图和列表, 然后使用GSON输出地图或列表对象

+1

你应该添加一个链接到GSON,理想情况下,发布一个示例代码片段或链接到你描述的方法的例子。 –

+0

好的,我是一个新人,所以答案可能会有点简单。我会发表另一个答案 –

3

JSON-lib的初步分析,并填充一个Java地图构建JSON字符串与输入JSON。不幸的是,JSON-lib然后检查每个JSON对象元素名称是否是JSON null。这是null检查在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}