LoginSignup
1
3

More than 3 years have passed since last update.

JavaでJSON文字列をエスケープするコード

Last updated at Posted at 2020-01-10

Javaで未だに公式サポートされないJSON

大きなデータの作成は、JacksonやGsonを使う選択肢が普通と思いますが、
小さなデータの作成は、リッチなライブラリに頼らず、簡単な関数で済ませたい。
このような時の悩みの種は文字列のエスケープ処理です。

エスケープ対象は、

対象文字 Byteコード エスケープ表記
BS 0x08 \b
HT 0x09 \t
LF 0x0A \n
FF 0x0C \f
CR 0x0D \r
" 0x22 \"
/ 0x2F \/
\ 0x5C \ \

コード

文字列を1バイトずつ置換する方式です。

private static String escapeJsonString(CharSequence cs) {

    final byte BACKSLASH = 0x5C;
    final byte[] BS = new byte[]{BACKSLASH, 0x62};  /* \\b */
    final byte[] HT = new byte[]{BACKSLASH, 0x74};  /* \\t */
    final byte[] LF = new byte[]{BACKSLASH, 0x6E};  /* \\n */
    final byte[] FF = new byte[]{BACKSLASH, 0x66};  /* \\f */
    final byte[] CR = new byte[]{BACKSLASH, 0x72};  /* \\r */

    try (
            ByteArrayOutputStream strm = new ByteArrayOutputStream();
            ) {

        byte[] bb = cs.toString().getBytes(StandardCharsets.UTF_8);

        for (byte b : bb) {

            if (b == 0x08 /* BS */) {

                strm.write(BS);

            } else if (b == 0x09 /* HT */) {

                strm.write(HT);

            } else if (b == 0x0A /* LF */) {

                strm.write(LF);

            } else if (b == 0x0C /* FF */) {

                strm.write(FF);

            } else if (b == 0x0D /* CR */) {

                strm.write(CR);

            } else if (
                    b == 0x22 /* " */
                    || b == 0x2F /* / */
                    || b == BACKSLASH /* \\ */
                    ) {

                strm.write(BACKSLASH);
                strm.write(b);

            } else {

                strm.write(b);
            }
        }

        return new String(strm.toByteArray(), StandardCharsets.UTF_8);
    }
    catch (IOException notHappen) {
        throw new RuntimeException(notHappen);
    }
}

テスト

public static void main(String[] args) {

    String before = "abc \b \t \n \f \r / \\ \"";
    String escaped = escapeJsonString(before);
    System.out.println("{\"value\":\"" + escaped + "\"}");

    /* {"value":"abc \b \t \n \f \r \/ \\ \""} */   
}
1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3