IT/Java

스프링 부트: 윈도우와 맥에서 한글 파일명 다운로드 문제 해결하기

Dev. Sean 2024. 1. 20. 13:57
반응형

문제 상황
스프링 부트(Spring Boot) 기반의 웹 애플리케이션에서 파일 다운로드 기능을 구현할 때, 맥(MacOS)에서는 한글 파일명이 정상적으로 다운로드되지만, 윈도우(Windows)에서는 한글 파일명이 깨지는 문제를 경험했습니다. 

이는 운영 체제 간의 문자 인코딩 처리 방식의 차이 때문에 발생하는 일반적인 문제입니다.

해결 방법
이 문제를 해결하기 위해, 한글 파일명을 UTF-8 인코딩으로 처리한 후, ISO-8859-1로 다시 인코딩하는 방식을 사용했습니다. 

또한, Content-Disposition 헤더를 적절히 설정하여 브라우저가 파일명을 올바르게 해석하도록 했습니다.

구현 코드
다음은 파일 다운로드를 처리하는 스프링 부트 컨트롤러의 일부 코드입니다:

try {
    // 파일 데이터 조회
    ResponseFile list = fileService.getFile(attachId, fileId);
    log.info("saveName ======>{} ", list.getSaveName());
    
    // 저장된 이름을 찾아 파일을 가지고옴
    Resource resource = fileUtils.readFileAsResource(list.getSaveName());

    // 파일명 UTF-8 인코딩 후, ISO-8859-1로 재인코딩
    String encodedFileName = new String(list.getOriginalName().getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);

    // Content-Disposition 설정
    String contentDisposition = "attachment; filename=\"" + encodedFileName + "\"; filename*=UTF-8''" + URLEncoder.encode(list.getOriginalName(), "UTF-8").replace("+", "%20");

    log.info("======================= FILE DOWNLOAD=======================");
    log.info("resource ======>{} ", resource);
    log.info("mimeType ======>{} ", list.getMediaType());
    log.info("encodedFileName ======>{} ", encodedFileName);
    log.info("============================================================");

    return ResponseEntity.ok()
            .contentType(MediaType.parseMediaType(list.getMediaType()))
            ...
}

 

UTF-8과 ISO-8859-1: 왜 변환 과정이 필요한가?
스프링 부트 애플리케이션에서 파일 다운로드 기능을 구현할 때, UTF-8 인코딩만 사용하면 윈도우에서 한글 파일명이 깨지는 문제가 있었습니다. 그렇다면 왜 이 문제가 발생하고, ISO-8859-1로 인코딩을 변환하면 왜 해결되는 걸까요?

UTF-8 인코딩의 문제점
브라우저 호환성: 많은 웹 브라우저와 서버는 Content-Disposition 헤더에서 ISO-8859-1 인코딩을 기대합니다. 

UTF-8로 인코딩된 파일명을 그대로 사용하면, 일부 브라우저(특히 구버전의 IE나 일부 오래된 브라우저)는 이를 제대로 해석하지 못하고 깨진 문자로 표시합니다.

표준과의 불일치: 초기 HTTP 표준은 Content-Disposition 헤더의 기본 인코딩으로 ISO-8859-1을 사용했습니다. 

이로 인해 새로운 표준인 UTF-8을 사용하는 것과 불일치가 발생합니다.

ISO-8859-1 인코딩으로의 해결책
인코딩 변환을 통한 호환성 확보: UTF-8 인코딩된 문자열을 먼저 ISO-8859-1 바이트 배열로 변환한 후, 다시 UTF-8 문자열로 해석하는 방법을 사용합니다. 

이는 헤더에 UTF-8로 인코딩된 한글 문자열을 넣을 수 있게 하면서도, 다양한 브라우저와 서버에서 올바르게 해석될 수 있도록 하는 '트릭'입니다.

브라우저 간 호환성 증가: 이 방식을 사용하면 윈도우와 맥을 비롯한 다양한 환경에서 한글 파일명이 깨지지 않고 정상적으로 다운로드됩니다.

 

중요 포인트
인코딩 처리: 파일명을 먼저 UTF-8로 인코딩한 후 ISO-8859-1로 다시 인코딩하여, 다양한 브라우저와 운영 체제에서 한글 파일명이 깨지지 않도록 처리했습니다.

Content-Disposition 헤더: 이 헤더를 사용하여 브라우저에 파일의 이름과 다운로드 여부를 알려줍니다. 

여기서 UTF-8 인코딩된 파일명을 명시함으로써, 한글 파일명이 정상적으로 처리될 수 있도록 했습니다.

결론
이 방법을 통해 윈도우 및 맥 환경에서 한글 파일명이 포함된 파일을 정상적으로 다운로드할 수 있게 되었습니다. 이 글이 파일 다운로드 기능을 구현할 때 문자 인코딩 문제로 어려움을 겪고 계신 분들께 도움이 되기를 바랍니다.

반응형