Java 報告された事例からメッセージ文を書き写したもので、ここでは実行していません。
Illegal unquoted character ((CTRL-CHAR, code 10))
ドキュメント内の文字列に、生の制御文字が含まれています。コード10は改行、13は復帰、9はタブです。JSONはこれらのエスケープを要求しており、Jacksonが拒否するのは正しい挙動です。V8が「bad control character」と呼ぶのと同じ根本問題です。
JSONを貼り付けて、壊れている箇所を正確に確認する
入力
貼り付けたものがブラウザの外に出ることはありません。 connect-src の許可リストにより、これは約束ではなくブラウザによる保証になっています。 自分で確かめる
実際の原因
どれが答えになることが多いか、その順に並べています。
-
01 文字列に埋め込まれた複数行テキスト
SQL、スタックトレース、ログの行、テンプレートの内容は、いずれも本物の改行を含みます。
壊れる例
{ "query": "SELECT * FROM users" }動く例
{ "query": "SELECT *\nFROM users" } -
02 連結で組み立てたJSON
埋め込んだ値はエスケープされません。テキストを手で組み立てるのではなく、ObjectMapper.writeValueAsStringでシリアライズしてください。
壊れる例
String body = "{\"note\": \"" + note + "\"}";動く例
String body = mapper.writeValueAsString(Map.of("note", note)); -
03 値の中にあるWindowsの改行コード
復帰(コード13)は別個の制御文字であり、\rが必要です。
ほかのランタイムでの同じ間違い
根本にある問題は同一で、違うのは文言だけです。同僚がこれらのどれかを報告してきたなら、見ているものはあなたと同じです。
| JavaScript (V8) | Bad control character in string literal in JSON at position 11 (line 1 column 12) |
|---|---|
| Python | Invalid control character at: line 1 column 8 (char 7) |
よくある質問
- ALLOW_UNESCAPED_CONTROL_CHARSはどうですか?
- JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARSを使えばJacksonはそれらを受け入れます。生成する側を変えられない場合の応急策としては妥当です。ただしそれでドキュメントが妥当なJSONになるわけではないので、ほかの受け取り側は今後も失敗します。