JavaでJSON文字列をエスケープする
1. 概要
この短いチュートリアルでは、JavaでJSON文字列をエスケープする方法をいくつか示します。
最も人気のあるJSON処理ライブラリと、それらがどのように簡単なタスクをエスケープするかについて簡単に説明します。
2. 何が間違っているのでしょうか?
ユーザーが指定したメッセージをWebサービスに送信する単純で一般的なユースケースを考えてみましょう。 素朴に、私たちは試すかもしれません:
String payload = "{\"message\":\"" + message + "\"}";
sendMessage(payload);
しかし、実際には、これは多くの問題を引き起こす可能性があります。
最も簡単なのは、メッセージに引用が含まれている場合です。
{ "message" : "My "message" breaks json" }
さらに悪いのはthe user can knowingly break the semantics of the requestです。 彼が送信した場合:
Hello", "role" : "admin
その後、メッセージは次のようになります。
{ "message" : "Hello", "role" : "admin" }
最も簡単なアプローチは、引用符を適切なエスケープシーケンスに置き換えることです。
String payload = "{\"message\":\"" + message.replace("\"", "\\\"") + "\"}";
ただし、このアプローチは非常に脆弱です。
-
It needs to be done for every concatenated valueであり、すでにエスケープした文字列を常に念頭に置く必要があります
-
さらに、メッセージ構造は時間の経過とともに変化するため、this can become a maintenance headache
-
そしてそれはhard to read, making it even more error-proneです
簡単に言えば、より一般的なアプローチを採用する必要があります。 残念ながら、native JSON processing features are still in the JEP phaseであるため、さまざまなオープンソースのJSONライブラリに目を向ける必要があります。
幸い、severalのJSON処理ライブラリがあります。 最も人気のある3つを簡単に見てみましょう。
3. JSON-javaライブラリ
私たちのレビューで最も単純で最小のライブラリは、org.jsonとしても知られるJSON-javaです。
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();
これにより、「World」を引用符で囲み、エスケープします。
{
"message" : "Hello \"World\""
}
4. ジャクソン図書館
JSON処理用の最も人気があり用途の広いJavaライブラリの1つは、Jacksonです。
一見すると、Jackson behaves similarly to org.json:
Map 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は、多くの場合goes head to head with JacksonであるGoogleのライブラリです。
もちろん、org.json againで行ったのと同じように行うことができます。
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文字列をエスケープする方法を説明しました。
この記事に関連するすべてのコードは、over on Githubにあります。