반응형
기존 코드
@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 |