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.replaceAll("\"", "\\\"") + "\"}";
しかし、このアプローチは非常に脆弱です。
-
すべての連結値
に対して実行する必要があります。
どの文字列が既にエスケープされているかを常に覚えておいてください
また、メッセージ構造が時間とともに変化するにつれて、
これは次のようになります。
メンテナンスの頭痛
そして、
読みにくく、エラーがさらに発生しやすくなっています
簡単に言えば、より一般的なアプローチを採用する必要があります。残念ながら、
ネイティブJSON処理機能はまだhttp://openjdk.java.net/jeps/198[JEP phase]
にあるため、さまざまなオープンソースJSONライブラリに目を向ける必要があります。
幸いなことに、http://json.org[いくつかの]JSON処理ライブラリがあります。最も人気のある3つを簡単に見てみましょう。
3. JSON-javaライブラリ
私たちのレビューの中で最も単純で最小のライブラリはhttps://www.baeldung.com/java-org-json[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つはhttps://www.baeldung.com/jackson[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
はGoogleのライブラリで、よくhttps://www.baeldung.com/jackson-vs-gson[Jackson]と対戦することができます。
-
もちろん、
__ 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文字列をエスケープする方法を説明しました。
この記事に関連するすべてのコードはhttps://github.com/eugenp/tutorials/tree/master/json[Githubに掲載]にあります。