8

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

例如:

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 来实现这个目标。

4

2 回答 2

5

这对我有用 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\""}
于 2011-05-30T03:41:09.393 回答
1

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

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

如果字符串不以引号或单引号开头,并且不包含前导或尾随空格,并且不包含以下任何字符,则根本不需要引用字符串: { } [ ] / \ : , = ; # 如果它们看起来不像数字并且它们不是保留字 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 中出现引用。

于 2011-06-03T15:14:22.963 回答