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にあります。