1. Panoramica
In questo breve tutorial, mostreremo alcuni modi per eseguire l'escape di una stringa JSON in Java.
Faremo un rapido tour delle librerie di elaborazione JSON più popolari e di come semplificano la fuga.
2. Cosa potrebbe andare storto?
Consideriamo un caso d'uso semplice ma comune di invio di un messaggio specificato dall'utente a un servizio Web. Ingenuamente, potremmo provare:
String payload = "{\"message\":\"" + message + "\"}"; sendMessage(payload);
Ma, davvero, questo può introdurre molti problemi.
Il più semplice è se il messaggio contiene una citazione:
{ "message" : "My "message" breaks json" }
La cosa peggiore è che l'utente può rompere consapevolmente la semantica della richiesta . Se invia:
Hello", "role" : "admin
Quindi il messaggio diventa:
{ "message" : "Hello", "role" : "admin" }
L'approccio più semplice è sostituire le virgolette con la sequenza di escape appropriata:
String payload = "{\"message\":\"" + message.replace("\"", "\\\"") + "\"}";
Tuttavia, questo approccio è piuttosto fragile:
- Deve essere fatto per ogni valore concatenato e dobbiamo sempre tenere a mente quali stringhe abbiamo già fatto
- Inoltre, poiché la struttura del messaggio cambia nel tempo, questo può diventare un problema di manutenzione
- Ed è difficile da leggere, il che lo rende ancora più soggetto a errori
In poche parole, dobbiamo utilizzare un approccio più generale. Sfortunatamente, le funzionalità di elaborazione JSON native sono ancora nella fase JEP , quindi dovremo rivolgere la nostra attenzione a una varietà di librerie JSON open source.
Fortunatamente, esistono diverse librerie di elaborazione JSON. Diamo una rapida occhiata ai tre più popolari.
3. Libreria JSON-java
La libreria più semplice e più piccola nella nostra recensione è JSON-java noto anche come org.json .
Per costruire un oggetto JSON, creiamo semplicemente un'istanza di JSONObject e fondamentalmente la trattiamo come una mappa :
JSONObject jsonObject = new JSONObject(); jsonObject.put("message", "Hello \"World\""); String payload = jsonObject.toString();
Questo prenderà le virgolette intorno a "World" e le sfuggirà:
{ "message" : "Hello \"World\"" }
4. Jackson Library
Una delle librerie Java più popolari e versatili per l'elaborazione JSON è Jackson.
A prima vista, Jackson si comporta in modo simile a org.json :
Map params = new HashMap(); params.put("message", "Hello \"World\""); String payload = new ObjectMapper().writeValueAsString(params);
Tuttavia, Jackson può anche supportare la serializzazione di oggetti Java.
Quindi miglioriamo un po 'il nostro esempio avvolgendo il nostro messaggio in una classe personalizzata:
class Payload { Payload(String message) { this.message = message; } String message; // getters and setters }
Quindi, abbiamo bisogno di un'istanza di ObjectMapper a cui possiamo passare un'istanza del nostro oggetto:
String payload = new ObjectMapper().writeValueAsString(new Payload("Hello \"World\""));
In entrambi i casi, otteniamo lo stesso risultato di prima:
{ "message" : "Hello \"World\"" }
Nei casi in cui abbiamo una proprietà già con escape e abbiamo bisogno di serializzarla senza ulteriori escape, potremmo voler usare l' annotazione @JsonRawValue di Jackson su quel campo.
5. Libreria Guava
Gson è una biblioteca di Google che spesso si scontra con Jackson.
Possiamo, ovviamente, fare di nuovo come abbiamo fatto con org.json :
JsonObject json = new JsonObject(); json.addProperty("message", "Hello \"World\""); String payload = new Gson().toJson(gsonObject);
Oppure possiamo usare oggetti personalizzati, come con Jackson:
String payload = new Gson().toJson(new Payload("Hello \"World\""));
E otterremo di nuovo lo stesso risultato.
6. Conclusione
In questo breve articolo, abbiamo visto come sfuggire alle stringhe JSON in Java utilizzando diverse librerie open source.
Tutto il codice relativo a questo articolo può essere trovato su Github.