Escape JSON String en Java

Escape JSON String en Java

1. Vue d'ensemble

Dans ce court tutoriel, nous allons montrer quelques façons d’échapper à une chaîne JSON en Java.

Nous allons faire un rapide tour d’horizon des bibliothèques de traitement JSON les plus populaires et expliquer en quoi elles simplifient l’échappement.

2. Qu'est-ce qui pourrait mal se passer?

Considérons un cas simple mais courant d’envoi d’un message spécifié par l’utilisateur à un service Web. Naïvement, nous pourrions essayer:

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

Mais, en réalité, cela peut poser de nombreux problèmes.

Le plus simple est si le message contient une citation:

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

Pire encore,the user can knowingly break the semantics of the request. S'il envoie:

Hello", "role" : "admin

Alors le message devient:

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

La méthode la plus simple consiste à remplacer les guillemets par la séquence d'échappement appropriée:

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

Cependant, cette approche est assez fragile:

  • It needs to be done for every concatenated value, et nous devons toujours garder à l'esprit les chaînes que nous avons déjà échappées

  • De plus, à mesure que la structure du message change avec le temps,this can become a maintenance headache

  • Et c'esthard to read, making it even more error-prone

En termes simples, nous devons utiliser une approche plus générale. Malheureusement,native JSON processing features are still in the JEP phase, nous devrons donc nous tourner vers une variété de bibliothèques JSON open source.

Heureusement, il existe des bibliothèques de traitement JSONseveral. Jetons un coup d'œil aux trois plus populaires.

3. Bibliothèque JSON-java

La bibliothèque la plus simple et la plus petite de notre revue estJSON-java également connue sous le nom deorg.json.

Pour construire un objet 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();

Cela prendra les guillemets autour de "Monde" et leur échappera:

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

4. Bibliothèque Jackson

L'une des bibliothèques Java les plus populaires et les plus polyvalentes pour le traitement JSON estJackson.

À première vue,Jackson behaves similarly to org.json:

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

Cependant, Jackson peut également prendre en charge la sérialisation des objets Java.

Alors améliorons un peu notre exemple en enveloppant notre message dans une classe personnalisée:

class Payload {
    Payload(String message) {
        this.message = message;
    }

    String message;

    // getters and setters
}

Ensuite, nous avons besoin d'une instance deObjectMapper à laquelle nous pouvons passer une instance de notre objet:

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

Dans les deux cas, nous obtenons le même résultat qu'auparavant:

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

Dans les cas où nous avons une propriété déjà échappée et que nous devons la sérialiser sans autre échappement, nous pouvons vouloir utiliser l'annotation@JsonRawValue de Jackson sur ce champ.

5. Bibliothèque de goyave

Gson est une bibliothèque de Google qui souventgoes head to head with Jackson.

Nous pouvons, bien sûr, faire comme nous l'avons fait avecorg.json again:

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

Ou nous pouvons utiliser des objets personnalisés, comme avec Jackson:

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

Et nous obtiendrons à nouveau le même résultat.

6. Conclusion

Dans ce court article, nous avons vu comment échapper des chaînes JSON en Java à l'aide de différentes bibliothèques Open Source.

Tout le code lié à cet article se trouveover on Github.