How to force JSON-lib's JSONObject.put(..) to escape a string containing JSON?

血红的双手。 提交于 2019-11-28 07:36:48

问题


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.


回答1:


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.




回答2:


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\""}

Is that a possible solution for you?

UPDATE:

Revised my answer with a possible solution



来源:https://stackoverflow.com/questions/6155560/how-to-force-json-libs-jsonobject-put-to-escape-a-string-containing-json

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!