Escape JSON String в Java

1. Общ преглед

В този кратък урок ще покажем някои начини за избягване на JSON низ в Java.

Ще направим кратка обиколка на най-популярните библиотеки за обработка на JSON и как те правят бягството от проста задача.

2. Какво може да се обърка?

Нека разгледаме прост, но често използван случай на изпращане на съобщение, зададено от потребителя, до уеб услуга. Наивно бихме могли да опитаме:

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

Но наистина това може да доведе до много проблеми.

Най-простото е, ако съобщението съдържа цитат:

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

По-лошото е, че потребителят може съзнателно да наруши семантиката на заявката . Ако той изпрати:

Hello", "role" : "admin

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

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

Най-простият подход е да замените кавичките с подходящата екранираща последователност:

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

Този подход обаче е доста крехък:

  • Трябва да се направи за всяка обединена стойност и ние винаги трябва да имаме предвид кои низове вече сме избягали
  • Освен това, тъй като структурата на съобщенията се променя с течение на времето, това може да се превърне в главоболие за поддръжка
  • И е трудно за четене, което го прави още по-податлив на грешки

Просто казано, трябва да използваме по-общ подход. За съжаление, родните функции за обработка на JSON все още са във фаза JEP , така че ще трябва да насочим вниманието си към различни JSON библиотеки с отворен код.

За щастие има няколко библиотеки за обработка на JSON. Нека да разгледаме набързо трите най-популярни.

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

Най-простата и малка библиотека в нашия преглед е JSON-java, известна също като org.json .

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

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

Това ще вземе цитатите около „Свят“ и ще им избяга:

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

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

Една от най-популярните и гъвкави Java библиотеки за обработка на JSON е Jackson.

На пръв поглед Джаксън се държи подобно на 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\"" }

В случаите, когато имаме вече избягало свойство и трябва да го сериализираме без допълнително избягване, може да поискаме да използваме анотацията на Jackson @JsonRawValue в това поле.

5. Библиотека Гуава

Gson е библиотека от Google, която често се среща с Джексън.

Разбира се, можем отново да направим това, което направихме с 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.