파일 업로드 시 가장 많이 사용하는 것 중 하나가 'MultipartFile'이다. 하지만 'MultipartFile'를 이용할 때, 파일 이름을 가져오는 과정에서 발생하는 문제가 발생했다. 나의 경험을 바탕으로 이 문제와 그에 대한 해결방법을 공유하고자 한다.
1. 발견 및 문제점
발견
목록에서 조회 api를 작성하는데 간단한 검색기능이 같이 들어갔다. 보통은 querydsl의 contains함수를 이용해 저장되어 있는 데이터에 프론트로부터 받은 검색어가 포함되어 있는 데이터를 조회하는 간단한 검색기능이었다. 그러나 이번엔 도통 부분검색이 되지않았다.
보통은 파일을 업로드 할 때 MultipartFile의 'getOriginalFilename()'메서드를 사용하여 File이름을 간단하게 가져올 수 있다
String originFilename = multipartFile.getOriginalFilename
하지만 이번에는 용량이 큰 영상파일 업로드를 구현했고 그에 따라 빠르고 가벼운 청크파일 업로드로 진행했다. 프론트에서 파일을 청크로 나누어 하나씩 보내주고 백에서 이를 모아 하나의 파일로 합친다. 이 과정에서 프론트에서 파일 이름을 같이 받아 저장했데 아무래도 여기서 문제가 생긴듯하다.
'LIKE CONCAT('%', "제목일부", '%')'를 사용하여 검색해도 부분검색이 되지 않았다.
문제점
문제를 분석해본 결과, 'MultipartFile'의 'getOriginalFilename()' 메서드를 사용하여 파일 이름을 가져올 때, 파일 이름에 한글이 포함된 경우 문제가 발생하였다.
이는 OS마다 유니코드를 처리하는 방식의 차이로 인한 문제였다. 특히, 맥 OS에서는 한글의 자음과 모음이 분리되어 처리되는데, 이로 인해 데이터베이스에 삽입된 파일명이 실제로 보는 것과 다르게 저장되어 검색이 제대로 이루어지지 않았다.
맥은 NFD(조합형), 윈도우는 NFC(완성형) 방식을 사용한다
// 맥에서 한글 처리 방식(NFD)
["ㅎ", "ㅏ", "ㄴ", "ㄱ", "ㅡ", "ㄹ"]
// 윈도우에서 한글 처리 방식(NFC)
["한", "글"]
2. 해결방법
이 문제를 해결하기 위해 맥에서 파일명을 받아 올 경우 NFC 방식으로 변환 하는 과정이 필요했다.
'Normalizer' 클래스의 'normalize()' 메서드를 사용하여 유니코드를 NFC 형태로 정규화하는 방법을 적용하였다. 이렇게 하면, 파일 이름을 가져온 후, OS에 관계없이 일관된 방식으로 파일 이름을 처리할 수 있다.
String originFilename = Normalizer.normalize(multipartFile.getOriginalFilename(), Normalizer.Form.NFC);
이 코드를 적용하니, 파일 이름에 한글이 포함된 경우에도 부분 검색이 정상적으로 동작하였다.
3. 정리 및 느낀점
이번 포스팅을 통해 'MultipartFile'에서 파일 이름을 가져오는 과정에서 발생할 수 있는 문제와 그에 대한 해결방법을 정리하였다. 그동안은 맥을 이용하면서 한번씩 파일 이름이 'ㅎㅏㄴㄱㅡㄹ' 이런식으로 깨져있는 것을 봤었지만 크게 신경쓰지 않고 넘겼었다. 이번 문제를 통해 유니코드에 대해서도 이해하고 처리방식에 대해서도 배울 수 있었다. 사소한 부분일 수 있지만 큰 문제가 될 수도 있기 때문에 이후에는 개발 할 때 주의해야겠다.
'개발 하나둘셋 > Java & Spring' 카테고리의 다른 글
Redis 서버 재시작 시 데이터 초기화 문제와 해결 방법: RDB와 AOF (1) | 2024.01.21 |
---|---|
Redis를 활용한 효율적인 조회수 관리 방법 (2) | 2024.01.04 |
AWS SDK for Java V1, V2 차이 / s3객체 업로드, 복사, 삭제 구현하기 (0) | 2023.06.26 |
TeamCity로 CI/CD 적용하기 (0) | 2022.11.10 |
Docker 알아보기! Dockerfile 만들기, 이미지와 컨테이너 빌드하기 (1) | 2022.09.16 |