RFC7159では以下をエスケープすると定義されています。
RFC7159
" quotation mark U+0022
\ reverse solidus U+005C
/ solidus U+002F
\b backspace U+0008
\f form feed U+000C
\n line feed U+000A
\r carriage return U+000D
\t tab U+0009
しかし、Jacksonのデフォルト設定では/
はエスケープされません。
CharacterEscapes
Jacksonのエスケープ対象文字を制御するには CharacterEscapes を使用します。
エスケープ方法は以下の3種類があります。
- \(バックスラッシュ)を付与(
\/
) - \uXXXXフォーマット(
\u002F
) - 任意の内容(
あああ
など)
1. \(バックスラッシュ)を付与
CharacterEscapes#getEscapeCodesForAscii()
で返すint[]
の'/'
番目の要素を'/'
にします。
CharacterEscapes#getEscapeSequence()
の戻り値はnull
でOK.
ObjectMapper mapper = new ObjectMapper();
mapper.getFactory().setCharacterEscapes(new CharacterEscapes() {
private final int[] escapeCodes;
{
escapeCodes = standardAsciiEscapesForJSON();
escapeCodes['/'] = '/';
}
@Override
public int[] getEscapeCodesForAscii() {
return escapeCodes;
}
@Override
public SerializableString getEscapeSequence(int ch) {
return null;
}
});
エスケープとアンエスケープ
https://qiita.com -> "https:\/\/qiita.com" -> https://qiita.com
2. \uXXXXフォーマット
'/'
番目の要素をESCAPE_STANDARD
にします。他は同じ。
{
escapeCodes = standardAsciiEscapesForJSON();
escapeCodes['/'] = ESCAPE_STANDARD;
}
エスケープとアンエスケープ
https://qiita.com -> "https:\u002F\u002Fqiita.com" -> https://qiita.com
3. 任意の内容
'/'
番目の要素をESCAPE_CUSTOM
にして、
エスケープ後文字列を指定したSerializableString
を返します。
{
escapeCodes = standardAsciiEscapesForJSON();
escapeCodes['/'] = ESCAPE_STANDARD;
}
@Override
public SerializableString getEscapeSequence(int ch) {
return new SerializedString("あああ");
}
エスケープとアンエスケープ
https://qiita.com -> "https:ああああああqiita.com" -> https:ああああああqiita.com
もちろん、上のような適当なエスケープでは元には戻らない。。。