JavaでJSON文字列をエスケープする
1. 概要
この短いチュートリアルでは、JavaでJSON文字列をエスケープするいくつかの方法を示します。
最も人気のあるJSON処理ライブラリと、それらが簡単なタスクをエスケープする方法について簡単に説明します。
2. 何がうまくいかないのでしょうか?
ユーザー指定のメッセージをWebサービスに送信する単純でありながら一般的なユースケースを考えてみましょう。 素朴に、私たちは試みるかもしれません:
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つを簡単に見てみましょう。
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. ジャクソン図書館
JSON処理用の最も人気があり用途の広いJavaライブラリの1つは、Jacksonです。
一見すると、Jacksonはorg.json:と同じように動作します
Map<String, Object> params = new HashMap<>();
params.put("message", "Hello \"World\"");
String payload = new ObjectMapper().writeValueAsString(params);
ただし、Jacksonは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ライブラリ
Gson は、がJacksonと直接対決することが多いGoogleのライブラリです。
もちろん、org.jsonで行ったのと同じように行うことができます。
JsonObject json = new JsonObject();
json.addProperty("message", "Hello \"World\"");
String payload = new Gson().toJson(gsonObject);
または、Jacksonのようにカスタムオブジェクトを使用できます。
String payload = new Gson().toJson(new Payload("Hello \"World\""));
そして、再び同じ結果が得られます。
6. 結論
この短い記事では、さまざまなオープンソースライブラリを使用してJavaでJSON文字列をエスケープする方法を見てきました。
この記事に関連するすべてのコードは、Githubのにあります。