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