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 값 안의 윈도우 줄바꿈
캐리지 리턴(코드 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이 되는 건 아니어서, 그것을 소비하는 다른 모든 것은 여전히 실패합니다.