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

发布于 2024-11-10 00:04:12 字数 1740 浏览 0 评论 0原文

使用 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"));

prints:

{"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 无法实现此目标。

When using JSON-lib's JSONObject, how can I stop the put method from storing a String which contains JSON as JSON rather than as an escaped string?

For instance:

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

prints:

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

and I want it to print:

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

Yes, I realize this is obnoxious. However, this is in support of a JSON serialization pipeline for which, for interoperability's sake, this is the expected behavior. There are cases in which we would be serializing user input which may be/contain valid JSON. We wouldn't want the user input to become a part of the JSON object that we're serializing said input to.

Manual escaping doesn't work because it causes JSON-lib to escape the \ characters:

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

Output:

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

At this point, any workarounds to enable manual selective escaping of a complex JSON object would completely negate the value of using JSON-lib in the first place.

Also, I understand that this question has been asked before, but unfortunately I cannot accept its answer so easily. JSON-lib is a heavily-used dependency in many areas of my project and swapping it out would be a big undertaking. I need to be absolutely sure that there's no way to achieve this goal with JSON-lib before I can entertain a swap to Jackson, simple-json, or Gson.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

森末i 2024-11-17 00:04:12

这对我来说适用于 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\""}

This worked for me with json-lib 2.4:

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

The output is:

{"jsonStringValue":"{\"hello\":\"world\"}","naturalStringValue":"\"hello world\""}
拿命拼未来 2024-11-17 00:04:12

使用单引号来引用字符串。来自文档

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

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

Use single quotes to quote the string. From the documentation:

Strings may be quoted with ' (single quote).

Strings do not need to be quoted at all if they do not begin with a quote or single quote, and if they do not contain leading or trailing spaces, and if they do not contain any of these characters: { } [ ] / \ : , = ; # and if they do not look like numbers and if they are not the reserved words true, false, or null.

So modifying your example:

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

Produces:

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

Note how quotedJsonStringValue has been treated as a string value and not JSON, and appears quoted in the output JSON.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文