2011-07-14 221 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}