Перейти к основному содержимому

Экранировать строку JSON в Java

· 3 мин. чтения

1. Обзор

В этом кратком руководстве мы покажем несколько способов экранирования строки JSON в Java.

Мы совершим краткий обзор самых популярных библиотек для обработки JSON и того, как с их помощью избежать простой задачи.

2. Что может пойти не так?

Давайте рассмотрим простой, но распространенный случай отправки указанного пользователем сообщения в веб-службу. Наивно, мы могли бы попробовать:

String payload = "{\"message\":\"" + message + "\"}";
sendMessage(payload);

Но, на самом деле, это может создать много проблем.

Самое простое, если сообщение содержит цитату:

{ "message" : "My "message" breaks json" }

Хуже того, пользователь может намеренно нарушить семантику запроса . Если он посылает:

Hello", "role" : "admin

Тогда сообщение становится:

{ "message" : "Hello", "role" : "admin" }

Самый простой подход — заменить кавычки соответствующей escape-последовательностью:

String payload = "{\"message\":\"" + message.replace("\"", "\\\"") + "\"}";

Однако этот подход довольно хрупок:

  • Это необходимо сделать для каждого конкатенированного значения , и нам нужно всегда помнить, какие строки мы уже экранировали.
  • Более того, поскольку структура сообщения со временем меняется, это может стать головной болью при обслуживании.
  • И это трудно читать, что делает его еще более подверженным ошибкам .

Проще говоря, нам нужно использовать более общий подход. К сожалению, нативные функции обработки JSON все еще находятся на стадии JEP , поэтому нам придется обратить внимание на различные библиотеки JSON с открытым исходным кодом.

К счастью, существует несколько библиотек обработки JSON. Давайте кратко рассмотрим три самых популярных из них.

3. Библиотека JSON-java

Самая простая и маленькая библиотека в нашем обзоре — это JSON-java, также известная как org.json .

Чтобы создать объект JSON, мы просто создаем экземпляр JSONObject и в основном обрабатываем его как карту :

JSONObject jsonObject = new JSONObject();
jsonObject.put("message", "Hello \"World\"");
String payload = jsonObject.toString();

Это возьмет кавычки вокруг «World» и избежит их:

{
"message" : "Hello \"World\""
}

4. Библиотека Джексона

Одна из самых популярных и универсальных библиотек Java для обработки JSON — Jackson .

На первый взгляд Джексон ведет себя аналогично org.json :

Map<String, Object> 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, которая часто конкурирует с Jackson .

Мы можем, конечно, снова сделать то, что мы сделали с org.json :

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, используя различные библиотеки с открытым исходным кодом.

Весь код, относящийся к этой статье, можно найти на Github .