Escapar JSON String em Java
1. Visão geral
Neste breve tutorial, mostraremos algumas maneiras de escapar de uma string JSON em Java.
Faremos um rápido tour pelas bibliotecas de processamento JSON mais populares e como elas tornam a fuga uma tarefa simples.
2. O que poderia dar errado?
Vamos considerar um caso de uso simples e comum de enviar uma mensagem especificada pelo usuário para um serviço da web. Ingenuamente, podemos tentar:
String payload = "{\"message\":\"" + message + "\"}";
sendMessage(payload);
Mas, realmente, isso pode apresentar muitos problemas.
O mais simples é se a mensagem contiver uma citação:
{ "message" : "My "message" breaks json" }
Pior éthe user can knowingly break the semantics of the request. Se ele enviar:
Hello", "role" : "admin
Então a mensagem se torna:
{ "message" : "Hello", "role" : "admin" }
A abordagem mais simples é substituir aspas pela sequência de escape apropriada:
String payload = "{\"message\":\"" + message.replace("\"", "\\\"") + "\"}";
No entanto, essa abordagem é bastante frágil:
-
It needs to be done for every concatenated value, e precisamos sempre ter em mente quais strings já escapamos
-
Além disso, conforme a estrutura da mensagem muda ao longo do tempo,this can become a maintenance headache
-
E éhard to read, making it even more error-prone
Simplificando, precisamos empregar uma abordagem mais geral. Infelizmente,native JSON processing features are still in the JEP phase, então teremos que voltar nossos olhos para uma variedade de bibliotecas JSON de código aberto.
Felizmente, existemseveral bibliotecas de processamento JSON. Vamos dar uma olhada rápida nos três mais populares.
3. Biblioteca JSON-java
A menor e mais simples biblioteca em nossa revisão éJSON-java, também conhecida comoorg.json.
Para construir um objeto 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();
Isso pegará as aspas em torno de "Mundo" e as escapará:
{
"message" : "Hello \"World\""
}
4. Jackson Library
Uma das bibliotecas Java mais populares e versáteis para processamento JSON éJackson.
À primeira vista,Jackson behaves similarly to org.json:
Map params = new HashMap<>();
params.put("message", "Hello \"World\"");
String payload = new ObjectMapper().writeValueAsString(params);
No entanto, Jackson também pode suportar a serialização de objetos Java.
Então, vamos aprimorar nosso exemplo um pouco envolvendo nossa mensagem em uma classe personalizada:
class Payload {
Payload(String message) {
this.message = message;
}
String message;
// getters and setters
}
Então, precisamos de uma instância deObjectMapper para a qual podemos passar uma instância do nosso objeto:
String payload = new ObjectMapper().writeValueAsString(new Payload("Hello \"World\""));
Nos dois casos, obtemos o mesmo resultado de antes:
{
"message" : "Hello \"World\""
}
Nos casos em que temos uma propriedade já com escape e precisamos serializá-la sem nenhum escape adicional, podemos usar a anotação@JsonRawValue de Jackson nesse campo.
5. Biblioteca Guava
Gson é uma biblioteca do Google que costumagoes head to head with Jackson.
Podemos, é claro, fazer como fizemos comorg.json novamente:
JsonObject json = new JsonObject();
json.addProperty("message", "Hello \"World\"");
String payload = new Gson().toJson(gsonObject);
Ou podemos usar objetos personalizados, como com Jackson:
String payload = new Gson().toJson(new Payload("Hello \"World\""));
E vamos obter novamente o mesmo resultado.
6. Conclusão
Neste breve artigo, vimos como escapar de strings JSON em Java usando diferentes bibliotecas de código aberto.
Todo o código relacionado a este artigo pode ser encontradoover on Github.