1. Overview
In this short tutorial, we’ll show some ways to escape a JSON string in Java.
We’ll take a quick tour of the most popular JSON-processing libraries and how they make escaping a simple task.
2. What Could Go Wrong?
Let’s consider a simple yet common use case of sending a user-specified message to a web service. Naively, we might try:
String payload = "{\"message\":\"" + message + "\"}";
sendMessage(payload);
But, really, this can introduce many problems.
The simplest is if the message contains a quote:
{ "message" : "My "message" breaks json" }
Worse is the user can knowingly break the semantics of the request. If he sends:
Hello", "role" : "admin
Then the message becomes:
{ "message" : "Hello", "role" : "admin" }
The simplest approach is to replace quotes with the appropriate escape sequence:
String payload = "{\"message\":\"" + message.replace("\"", "\\\"") + "\"}";
However, this approach is quite brittle:
- It needs to be done for every concatenated value, and we need to always keep in mind which strings we’ve already escaped
- Moreover, as the message structure changes over time, this can become a maintenance headache
- And it’s hard to read, making it even more error-prone
Simply put, we need to employ a more general approach. Unfortunately, native JSON processing features are still in the JEP phase, so we’ll have to turn our sights to a variety of open source JSON libraries.
Fortunately, there are several JSON processing libraries. Let’s take a quick look at the three most popular ones.
3. JSON-java Library
The simplest and smallest library in our review is JSON-java also known as org.json.
To construct a JSON object, we simply create an instance of JSONObject and basically treat it like a Map:
JSONObject jsonObject = new JSONObject();
jsonObject.put("message", "Hello \"World\"");
String payload = jsonObject.toString();
This will take the quotes around “World” and escape them:
{
"message" : "Hello \"World\""
}
4. Jackson Library
One of the most popular and versatile Java libraries for JSON processing is Jackson.
At first glance, Jackson behaves similarly to org.json:
Map<String, Object> params = new HashMap<>();
params.put("message", "Hello \"World\"");
String payload = new ObjectMapper().writeValueAsString(params);
However, Jackson can also support serializing Java objects.
So let’s enhance our example a bit by wrapping our message in a custom class:
class Payload {
Payload(String message) {
this.message = message;
}
String message;
// getters and setters
}
Then, we need an instance of ObjectMapper to which we can pass an instance of our object:
String payload = new ObjectMapper().writeValueAsString(new Payload("Hello \"World\""));
In both cases, we get the same result as before:
{
"message" : "Hello \"World\""
}
In cases where we have an already-escaped property and need to serialize it without any further escaping, we may want to use Jackson’s @JsonRawValue annotation on that field.
5. Gson Library
Gson is a library from Google that often goes head to head with Jackson.
We can, of course, do as we did with org.json again:
JsonObject json = new JsonObject();
json.addProperty("message", "Hello \"World\"");
String payload = new Gson().toJson(gsonObject);
Or we can use custom objects, like with Jackson:
String payload = new Gson().toJson(new Payload("Hello \"World\""));
And we’ll again get the same result.
6. Conclusion
In this short article, we’ve seen how to escape JSON strings in Java using different open source libraries.
All the code related to this article can be found over on Github.