如何强制JSON-lib的JSONObject.put(..)转义包含JSON的字符串?

使用JSON-lib的JSONObject ,如何阻止put方法存储包含JSON作为JSON而不是转义字符串的String?

例如:

 JSONObject obj = new JSONObject(); obj.put("jsonStringValue","{\"hello\":\"world\"}"); obj.put("naturalStringValue", "\"hello world\""); System.out.println(obj.toString()); System.out.println(obj.getString("jsonStringValue")); System.out.println(obj.getString("naturalStringValue")); 

打印:

 {"jsonStringValue":{"hello":"world"},"naturalStringValue":"\"hello world\""} {"hello":"world"} "hello world" 

我希望它打印:

 {"jsonStringValue":"{\"hello\":\"world\"}","naturalStringValue":"\"hello world\""} {"hello":"world"} "hello world" 

是的,我意识到这是令人讨厌的。 但是,这支持JSON序列化管道,为了互操作性,这是预期的行为。 在某些情况下,我们会序列化可能包含有效JSON的用户输入。 我们不希望用户输入成为我们将所述输入序列化的JSON对象的一部分。

手动转义不起作用,因为它导致JSON-lib转义\字符:

 JSONObject obj = new JSONObject(); obj.put("naturalJSONValue","{\"hello\":\"world\"}"); obj.put("escapedJSONValue", "{\\\"hello\\\":\\\"world\\\"}"); System.out.println(obj.toString()); System.out.println(obj.getString("naturalJSONValue")); System.out.println(obj.getString("escapedJSONValue")); 

输出:

 {"naturalJSONValue":{"hello":"world"},"escapedJSONValue":"{\\\"hello\\\":\\\"world\\\"}"} {"hello":"world"} {\"hello\":\"world\"} 

此时,任何启用手动选择性转义复杂JSON对象的变通方法都会完全否定首先使用JSON-lib的价值。

另外,我知道之前已经提出这个问题,但不幸的是我不能轻易接受它的答案。 JSON-lib在我的项目的许多方面都是一个经常使用的依赖项,并且交换它将是一项艰巨的任务。 我需要绝对肯定在我可以接受与Jackson,simple-json或Gson的交换之前,没有办法用JSON-lib实现这个目标。

使用单引号引用字符串。 从文档 :

字符串可以用’(单引号)引用。

如果字符串不以引号或单引号开头,并且它们不包含前导或尾随空格,并且它们不包含任何这些字符,则根本不需要引用它们:{} [] / \: ,=; #并且如果它们看起来不像数字,并且它们不是保留字true,false或null。

所以修改你的例子:

 net.sf.json.JSONObject obj = new net.sf.json.JSONObject(); obj.put("jsonStringValue","{\"hello\":\"world\"}"); obj.put("quotedJsonStringValue","\'{\"hello\":\"world\"}\'"); obj.put("naturalStringValue", "\"hello world\""); System.out.println(obj.toString()); System.out.println(obj.getString("jsonStringValue")); System.out.println(obj.getString("quotedJsonStringValue")); System.out.println(obj.getString("naturalStringValue")); 

生产:

 {"jsonStringValue":{"hello":"world"},"quotedJsonStringValue":"{\"hello\":\"world\"}","naturalStringValue":"\"hello world\""} {"hello":"world"} {"hello":"world"} "hello world" 

请注意quotedJsonStringValue如何被视为字符串值而不是JSON,并在输出JSON中显示。

这适用于json-lib 2.4:

 System.out.println( new JSONStringer() .object() .key("jsonStringValue") .value("{\"hello\":\"world\"}") .key("naturalStringValue") .value("\"hello world\"") .endObject() .toString()); 

输出是:

 {"jsonStringValue":"{\"hello\":\"world\"}","naturalStringValue":"\"hello world\""} 

这是一个可能的解决方案吗?

更新:

用可能的解决方案修改了我的答案