ㅁㅐㄱㅇㅔㅅㅓ ㅎㅏㄴㄱㅡㄹ ㄲㅐㅈㅣㅁ(맥에서 한글 깨짐)
## 작성이유
같은 이슈가 주위에서 반복되고 있어 이슈처리 과정을 정리하여 공유하기 위해
## 발단 및 전개
1. 웹 어플리케이션에서 파일 업로드 기능을 사용하여 엑셀파일을 업로드한다.
2. 웹 어플리케이션에서 해당 엑셀 파일을 읽어 DB에 삽입한다
3. 삽입한 데이터를 원천으로 데이터 가공한다
4. 가공한 데이터를 사용자에게 엑셀 파일로 제공 한다
5. 테스트 및 리펙토링
5번 테스트 및 리펙토링 과정에서 파일을 다운로드 했는데 아래와 같이 한글이 깨지는 것을 확인할 수 있었습니다.
##### 엑셀 다운로드 셀 값 확인결과
## 위기
간단하게 인코딩 문제 인걸로 예측하고 원인 파악을 시작했습니다.
“ DB 값이 이상하게 들어갔을 테니 확인해보자 ”
라고 생각하고 데이터를 확인해 보았습니다.
“ 인코딩을 UTF-8 로 설정해보자 ”
1. IDE 인코딩을 UTF-8로 설정한다 ( -이미 설정이 되어있네?- )
2. -인코딩 이란 설정만 보이면 UTF-8로 설정한다-
엑셀 다운로드 셀 값 확인결과
## 절정
Debugger를 사용해서 값이 어디서 깨지는 것인지 체크해 보았습니다
1. 서버로 넘어오는 구간에서 디버깅
2. 서버에서 디비로 넘어가는 구간에서 디버깅
3. 디비에서 가져오는 구간에서 디버깅
그러나 깨지는 곳은 없었고 몇 시간째 삽질을 하던 도중
textEditor에 Debugger에 찍힌 값을 복사 붙여넣기 해서 봤더니
##### Debugger
#####Debugger의 값을 복사 붙여넣기한 TextEditor
TextEditor에서 깨진 값이 찍히는 것을 확인하였고 실제 값 자체가 깨져 있다는 것을 알 수 있었습니다 그렇다면 값이 어떻게 안 깨져 보였을까요?
이유는 친절하고 똑똑한 IDE 들이 자음과 모음을 조합해서 보여주고
있었던 것이었습니다
(// TODO : 어떤방식인지 정확하게 확인 필요)
-결국 제 잘못은 아니고 똑똑한 IDE 탓 입니다-
## 결말
*유니코드 정규화 방식* 차이로 인해 발생된 이슈였습니다
유니코드란?
전 세계의 모든 문자를 다루도록 설계된 표준 문자 전산 처리 방식. 이하 생략
*유니코드 정규화*(Unicode normalization)는 모양이 같은 여러 문자들이 있을 경우 이를 기준에 따라 하나로 통합해 주는 일을 가리킨다. 그 기준으로는 아래 표와 같이 NFD, NFC, NFKD, NFKC가 있다.
이 중 한글 처리와 관련된 것은
NFD(소리 마디를 코드로 분해) 와 NFC(코드를 소리 마디로 결합) 이다.
두가지방식을 OS 별로 구분해 보자면
NFD (Normalization Form Canonical Decomposition) : Mac에서 사용하는 방식
NFC (Normalization Form Canonical Composition) : 많은 GNU/Linux 시스
템, Windows에서 사용하는 방식 이다
현재 저의 로컬 환경은 Mac 환경을 사용하고 있으므로 NFD 방식으로 분해 되어있는 코드를 자바에서 제공하는 유니코드 정규화 기능 (Nomalizer) 을 사용하여 NFC 방식으로 결합하여 해당이슈를 처리하였습니다.
String fullFileName = multipartFile.getOriginalFilename(); // multipartFIle 객체에서 파일명을 가져온다String fileName = FilenameUtils.getBaseName(fullFileName); // 확장자를 제거한 파일명을 가져온다
String normalizeFileNameByNFC = Normalizer.normalize(FilenameUtils.getBaseName(multipartFile.getOriginalFilename()), Normalizer.Form.NFC); // NFC 형태로 normalize 한다
// or
String fileName = Normalizer.normalize(FilenameUtils.getBaseName(multipartFile.getOriginalFilename()), Normalizer.Form.NFC);