반응형
기존 코드
@GetMapping(value = "/download", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) @ResponseBody public ResponseEntity<Resource> downloadFile(String fileName) { Resource resource = new FileSystemResource("D:\\upload\\" + fileName); String resourceName = resource.getFilename(); HttpHeaders headers = new HttpHeaders(); try { headers.add("Content-Disposition", "attachment; filename=" + new String(resourceName.getBytes("UTF-8"), "ISO-8859-1")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return new ResponseEntity<Resource>(resource, headers, HttpStatus.OK); }
크롬(chrome)에서는
D:\upload 폴더에 있는 파일의 이름과 확장자로 '\download?fileName=XXXX'와 같이 호출하면 브라우저는 자동으로 해당 파일을 다운로드 받는다.
But.
IE(Internet Explorer), Edge 같은 경우 Chrome 브라우저와 달리 한글 이름이 제대로 다운로드 되지 않는 경욱 있다. 그 이유는 헤더에 전달하는 Content_disposition의 값을 처리하는 방식이 IE, Edge같은 경우 Chrome과 달리 인코딩 방식이 다르기 때문이다.
해결 코드
- HttpServletRequest에 포함된 헤더 정보들을 이용해서 요청이 발생한 브라우저가 IE인지 Chrome인지 Edge인지 확인해야 한다. 이를 위해 HTTP 헤더 메시지 중에서 디바이스의 정보를 알 수 있는 헤더는 'User-Agent' 값을 이용
※User-Agent: 브라우저의 종류 및 모바일인지 PC인지 알 수 있다. - @RequestHeader를 이용해 HTTP 헤더 메시지의 내용 중 User-Agent의 정보를 파악하여 각 브라우저 종류에 따라 다른 방식으로 처리해준다.
- UUID를 제거하여(resourceOriginalName 생성) 순수하게 다운로드 되는 파일의 이름으로 저장될 수 있게 함
@GetMapping(value = "/download", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) @ResponseBody public ResponseEntity<Resource> downloadFile(@RequestHeader("User-Agent") String userAgent, String fileName) { Resource resource = new FileSystemResource("D:\\upload\\" + fileName); if (resource.exists() == false) { return new ResponseEntity<Resource>(HttpStatus.NOT_FOUND); } String resourceName = resource.getFilename(); // remove UUID String resourceOriginalName = resourceName.substring(resourceName.indexOf("_") + 1); HttpHeaders headers = new HttpHeaders(); try { String downloadName = null; // IE(Internet Explorer if (userAgent.contains("Trident")) { downloadName = URLEncoder.encode(resourceOriginalName, "UTF-8").replaceAll("\\+", " "); } // Edge else if (userAgent.contains("Edge")) { downloadName = URLEncoder.encode(resourceOriginalName, "UTF-8"); } else { downloadName = new String(resourceOriginalName.getBytes("UTF-8"), "ISO-8859-1"); } headers.add("Content-Disposition", "attachment; filename=" + downloadName); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return new ResponseEntity<Resource>(resource, headers, HttpStatus.OK); }
반응형
'ETC' 카테고리의 다른 글
스프링 시큐리티를 이용한 로그인 (0) | 2022.09.30 |
---|---|
[springMVC + Ajax] 게시판 첨부파일 추가 (0) | 2022.09.27 |
Spring + Ajax 파일 다운로드 (0) | 2022.09.26 |
Spring + Ajax 섬네일 파일 생성, 이미지 파일인지 구분, 이미지 클릭 시 원본 이미지 출력 (0) | 2022.09.25 |
Spring + Ajax 중복된 파일 이름 해결 (0) | 2022.09.25 |