Spring Boot Undertow 환경에서 대용량 텍스트 멀티파트 전송 시 한글 깨짐 현상
여기에 맞게 적는지 모르겠으나.. 혹시 저와 비슷한 사람으로 인해 삽질하는 일이 없었으면 하는 내용으로 적습니다.
운영중인 프로젝트에서 금일 오전 부터 스프링 부트(Spring Boot)에서 기본 웹 서버인 Tomcat 대신 Jboss 를 사용하는 환경에서, multipart/form-data 요청 시 폼 텍스트 파라미터에 대용량 한글 데이터(대규모 JSON 문자열 등)가 포함될 경우 일부 한글이 깨지는 현상(U+FFFD 대체 문자로 치환됨)이 간헐적으로 발생했습니다.

일반적인 @RequestBody 방식의 JSON 전송이나 용량이 작은 텍스트 파라미터 전송 시에는 문제가 발생하지 않았으나, 텍스트 데이터의 용량이 커질 때만 랜던한 위치의 한글이 깨지는 것이 특징이었습니다.
현상의 근본적인 원인은 Undertow 서버가 대용량 멀티파트 데이터를 파싱할 때 내부적으로 사용하는 고정 크기 버퍼(Buffer) 로직에 있습니다.
수신된 데이터 크기가 일정 임계치를 초과하면, Undertow는 전체 스트림을 한 번에 메모리에 올리지 않고 물리적인 버퍼 경계(예: 16KB 단위)로 쪼개어서 읽어 들입니다.
한글과 같은 UTF-8 문자는 한 글자당 3바이트를 차지합니다. 만약 이 3바이트 문자가 물리적인 버퍼 경계선에 아슬아슬하게 걸치게 되면, 1바이트와 2바이트 조각으로 쪼개져서 서로 다른 버퍼로 나뉘어 유입됩니다.
Undertow의 멀티파트 내부 파서는 이렇게 잘린 버퍼 조각들을 각각 개별적으로 먼저 문자열로 디코딩 한 후에 하나로 합칩니다 . 이 과정에서 불완전한 바이트 조각들은 깨진 대체 문자(U+FFFD, ``)로 강제 치환되어 버리고, 결과적으로 API 단 에서 데이터를 처리할때 원본 데이터에 이상한 문자 들이 껴들게 됩니다.
이러한 대용량 텍스트 멀티파트 파라미터 이슈를 해결하기 위해 AI 의 도움을 받아 해결한 방법은 API 단에 데이터를 넘기 이전 서블릿 필터 단에서 처리하는 방법이었습니다.
서블릿 필터 단 에서 데이터를 Undertow가 문자열을 잘못 파싱하기 전에 스트림 원본을 꺼내어 안전하게 직접 디코딩하는 방식입니다.
HttpRequest 로 받은 데이터를 StandardMultipartHttpServletRequest 상속 받아 새롭게 로직을 구현하였습니다.
이렇게 하여 Undertow 가 데이터를 자르지 않고 들어온 데이터를 한번에 읽은뒤 UTF-8 로 변환한뒤 다시 컨트롤러에 던지게 됩니다.


스택오버플로우에도 올라온 버그인데… 이거 해결한다고 웹 으로 이리처리 찾아가면서 하다가 얻어 걸렸습니다.