Escape JSON String в Java
1. обзор
В этом коротком руководстве мы покажем несколько способов избежать использования строки JSON в Java.
Мы кратко рассмотрим самые популярные библиотеки JSON-обработки и то, как они позволяют избежать простой задачи.
2. Что может пойти не так?
Давайте рассмотрим простой, но распространенный вариант использования отправки пользовательского сообщения в веб-сервис. Наивно, мы могли бы попробовать:
String payload = "{\"message\":\"" + message + "\"}";
sendMessage(payload);
Но на самом деле это может создать много проблем.
Самое простое, если сообщение содержит цитату:
{ "message" : "My "message" breaks json" }
Хужеthe user can knowingly break the semantics of the request. Если он отправляет:
Hello", "role" : "admin
Тогда сообщение становится:
{ "message" : "Hello", "role" : "admin" }
Самый простой подход - заменить кавычки соответствующей escape-последовательностью:
String payload = "{\"message\":\"" + message.replace("\"", "\\\"") + "\"}";
Однако такой подход довольно хрупок:
-
It needs to be done for every concatenated value, и нам всегда нужно помнить, какие строки мы уже экранировали
-
Более того, поскольку структура сообщения меняется со временем,this can become a maintenance headache
-
И этоhard to read, making it even more error-prone
Проще говоря, нам нужно использовать более общий подход. К сожалению,native JSON processing features are still in the JEP phase, поэтому нам придется обратить внимание на различные библиотеки JSON с открытым исходным кодом.
К счастью, есть библиотеки обработки JSONseveral. Давайте кратко рассмотрим три самых популярных.
3. JSON-Java-библиотека
Самая простая и маленькая библиотека в нашем обзоре -JSON-java, также известная какorg.json.
Чтобы создать объект JSON,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();
Это возьмет кавычки вокруг «Мира» и избежит их:
{
"message" : "Hello \"World\""
}
4. Библиотека Джексона
Одна из самых популярных и универсальных библиотек Java для обработки JSON -Jackson.
На первый взглядJackson behaves similarly to org.json:
Map params = new HashMap<>();
params.put("message", "Hello \"World\"");
String payload = new ObjectMapper().writeValueAsString(params);
Однако Джексон также может поддерживать сериализацию объектов Java.
Итак, давайте немного улучшим наш пример, заключив наше сообщение в специальный класс:
class Payload {
Payload(String message) {
this.message = message;
}
String message;
// getters and setters
}
Затем нам нужен экземплярObjectMapper, которому мы можем передать экземпляр нашего объекта:
String payload = new ObjectMapper().writeValueAsString(new Payload("Hello \"World\""));
В обоих случаях мы получаем тот же результат, что и раньше:
{
"message" : "Hello \"World\""
}
В случаях, когда у нас уже есть экранированное свойство и нам нужно сериализовать его без дальнейшего экранирования, мы можем использовать аннотацию Джексона@JsonRawValue для этого поля.
5. Библиотека гуавы
Gson - это библиотека от Google, которая часто используетgoes head to head with Jackson.
Конечно, мы можем поступить так же, как сorg.json again:
JsonObject json = new JsonObject();
json.addProperty("message", "Hello \"World\"");
String payload = new Gson().toJson(gsonObject);
Или мы можем использовать пользовательские объекты, как с Джексоном:
String payload = new Gson().toJson(new Payload("Hello \"World\""));
И мы снова получим тот же результат.
6. Заключение
В этой короткой статье мы увидели, как избежать строк JSON в Java с помощью различных библиотек с открытым исходным кодом.
Весь код, относящийся к этой статье, можно найтиover on Github.