1

エンコードされた JSON 値をテストするために、Java で単体テストを作成しようとしています。私は次のことをしようとしています:

assertEquals(expectedJSON(),actualJSON())

expectedJSON()が返す場所

{
    "someHtml": {
        "html": "<html>HTML&CSS</html>"
    }
}

actualJSON()が返す場所

 {
        "someHtml": {
            "html": "\u003Chtml\u003EHTML\u0026CSS\u003C/html\u003E"
        }
    }

expectedJSON が actualJSON() が返すものを返すようにしたいのですが、これを行う簡単な方法がわかりません。私はオンラインで見ましたが、これについて簡単に見つけることができませんでした。actualJSON ()は複雑な処理を行っており、この方法で値を返す必要があります。私のexpectedJSON()メソッドは次のようになります

public String expectedJSONWithHTMLValues(){
        return "{" +
                    "\"someHtml\":{" +
                  "\"html\":\"\u003Chtml\u003EHTML\u0026CSS\u003C/html\u003E\"}}";
    }
4

2 に答える 2

6

他の答えに加えて、\uエスケープにはJavaで興味深いプロパティがあり、コンパイラによって実際に前処理されます( JLS §3.3 )。

これは、コンパイラに行く\uにソースファイルで文字が置き換えられることを意味します。したがって、あなたのコード:

public String expectedJSONWithHTMLValues(){
    return "{" +
           "\"someHtml\":{" +
           "\"html\":\"\u003Chtml\u003EHTML\u0026CSS\u003C/html\u003E\"}}";
}

次のように前処理されています。

public String expectedJSONWithHTMLValues(){
    return "{" +
           "\"someHtml\":{" +
           "\"html\":\"<html>HTML&CSS</html>\"}}";
}

そして、それがコンパイルされているものです。

Java コンパイラは\u、実際にファイルをコンパイルする前に、エスケープを文字に変換します。これは\u、変数名、クラス名、メソッド名などでエスケープを使用できることを意味します。コンパイラはそれを文字自体に変換し、コンパイル プロセスで使用します。\nこれが、の代わりに文字列で使用することになっている理由です\u000a。後者を使用した場合、ソース コードは次のようになります。

String s = "My\u000aNewline";

これに:

String s = "My
Newline";

Stringリテラルが複数の行に分割されているため、コンパイラ エラーが発生します。

これにより、いくつかの非常に悪いことを行うことができます。たとえば、これは 100% 正当な Java コードであり、どのオペレーティング システムでもコンパイルできます。

\u0070\u0075\u0062\u006c\u0069\u0063 \u0063\u006c\u0061\u0073\u0073 \u004d\u0061\u0069\u006e \u007b

    \u0070\u0072\u0069\u0076\u0061\u0074\u0065 \u0073\u0074\u0061\u0074\u0069\u0063 \u0053\u0074\u0072\u0069\u006e\u0067 \u0073\u006f\u006d\u0065\u0053\u0074\u0072\u0069\u006e\u0067 \u003d \u0022\u004d\u0079 \u0053\u0074\u0072\u0069\u006e\u0067\u0022\u003b

    \u0070\u0075\u0062\u006c\u0069\u0063 \u0073\u0074\u0061\u0074\u0069\u0063 \u0076\u006f\u0069\u0064 \u006d\u0061\u0069\u006e\u0028\u0053\u0074\u0072\u0069\u006e\u0067\u005b\u005d \u0061\u0072\u0067\u0073\u0029 \u007b
        \u0053\u0079\u0073\u0074\u0065\u006d\u002e\u006f\u0075\u0074\u002e\u0070\u0072\u0069\u006e\u0074\u006c\u006e\u0028\u0073\u006f\u006d\u0065\u0053\u0074\u0072\u0069\u006e\u0067\u0029\u003b
    \u007d
\u007d

それは印刷します:

My String

信じられない?自分で見て。コンパイラは最初にすべての\uエスケープを文字に\u0070\u0072\u0069\u0076\u0061\u0074\u0065変換しprivateます。\u0073\u0074\u0061\u0074\u0069\u0063\u0053\u0074\u0072\u0069\u006e\u0067String

とにかく、特定の問題を解決するには、次の\ように二重エスケープするだけです。

public String expectedJSONWithHTMLValues(){
    return "{" +
           "\"someHtml\":{" +
           "\"html\":\"\\u003Chtml\\u003EHTML\\u0026CSS\\u003C/html\\u003E\"}}";
}

また、次の String も注目に値します。

{"someHtml":{"html":"\u003Chtml\u003EHTML\u0026CSS\u003C/html\u003E"}}

空白が追加されたこの文字列と等しくありません:

{
    "someHtml": {
        "html": "\u003Chtml\u003EHTML\u0026CSS\u003C/html\u003E"
    }
}

String.equalsには空白が含まれるため、空白を含め、2 つの文字列が文字ごとに同一であることを確認してください。

于 2013-09-14T01:24:49.207 に答える
1

バックスラッシュは、書くときだけでなく、のようなものを書くときにも、String定数で特別な意味を持ちます。後者の場合、シーケンスは Unicode 文字 U+003C に置き換えられます。リテラルシーケンスが必要な場合は、バックスラッシュ自体を引用して、定数にバックスラッシュ文字を挿入する必要があります: ."\"""\u003C"\u003C'<'\u003CString"\\u003C"

String空白の違いにより、マッチングが失敗する可能性があることに注意してください。この空白は JSON の観点からは無視できるStringため、JSON 値の完全一致を実行することはお勧めできません。

于 2013-09-10T09:46:58.243 に答える