Escape JSON String in Java

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.