Escape JSON String en Java

1. Información general

En este breve tutorial, mostraremos algunas formas de escapar de una cadena JSON en Java.

Haremos un recorrido rápido por las bibliotecas de procesamiento JSON más populares y cómo hacen que escapar sea una tarea simple.

2. ¿Qué podría salir mal?

Consideremos un caso de uso simple pero común de enviar un mensaje especificado por el usuario a un servicio web. Ingenuamente, podríamos intentar:

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

Pero, realmente, esto puede presentar muchos problemas.

La más simple es si el mensaje contiene una cita:

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

Lo peor es que el usuario puede romper conscientemente la semántica de la solicitud . Si envía:

Hello", "role" : "admin

Entonces el mensaje se convierte en:

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

El enfoque más simple es reemplazar las comillas con la secuencia de escape adecuada:

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

Sin embargo, este enfoque es bastante frágil:

  • Debe hacerse para cada valor concatenado , y siempre debemos tener en cuenta las cadenas de las que ya hemos escapado.
  • Además, como la estructura del mensaje cambia con el tiempo, esto puede convertirse en un dolor de cabeza de mantenimiento.
  • Y es difícil de leer, lo que lo hace aún más propenso a errores.

En pocas palabras, debemos emplear un enfoque más general. Desafortunadamente, las funciones de procesamiento JSON nativas todavía están en la fase JEP , por lo que tendremos que dirigir nuestra mirada hacia una variedad de bibliotecas JSON de código abierto.

Afortunadamente, existen varias bibliotecas de procesamiento JSON. Echemos un vistazo rápido a los tres más populares.

3. Biblioteca JSON-java

La biblioteca más simple y pequeña de nuestra revisión es JSON-java, también conocida como org.json .

Para construir un objeto JSON, simplemente creamos una instancia de JSONObject y básicamente lo tratamos como un mapa :

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

Esto tomará las citas alrededor de "Mundo" y las escapará:

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

4. Biblioteca Jackson

Una de las bibliotecas de Java más populares y versátiles para el procesamiento JSON es Jackson.

A primera vista, Jackson se comporta de manera similar a org.json :

Map params = new HashMap(); params.put("message", "Hello \"World\""); String payload = new ObjectMapper().writeValueAsString(params);

Sin embargo, Jackson también puede admitir la serialización de objetos Java.

Así que mejoremos un poco nuestro ejemplo envolviendo nuestro mensaje en una clase personalizada:

class Payload { Payload(String message) { this.message = message; } String message; // getters and setters } 

Entonces, necesitamos una instancia de ObjectMapper a la que podemos pasar una instancia de nuestro objeto:

String payload = new ObjectMapper().writeValueAsString(new Payload("Hello \"World\"")); 

En ambos casos, obtenemos el mismo resultado que antes:

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

En los casos en que tengamos una propiedad que ya se haya escapado y necesitemos serializarla sin ningún otro escape, es posible que deseemos usar la anotación @JsonRawValue de Jackson en ese campo.

5. Biblioteca de guayaba

Gson es una biblioteca de Google que a menudo va cara a cara con Jackson.

Por supuesto, podemos volver a hacer lo mismo que hicimos con org.json :

JsonObject json = new JsonObject(); json.addProperty("message", "Hello \"World\""); String payload = new Gson().toJson(gsonObject);

O podemos usar objetos personalizados, como con Jackson:

String payload = new Gson().toJson(new Payload("Hello \"World\""));

Y nuevamente obtendremos el mismo resultado.

6. Conclusión

En este breve artículo, hemos visto cómo escapar de las cadenas JSON en Java utilizando diferentes bibliotecas de código abierto.

Todo el código relacionado con este artículo se puede encontrar en Github.