본문 바로가기
Language/Java

[JAVA] 다운로드 파일명/browser fileName 깨짐현상/브라우저 파일이름 깨짐/파일 한글 깨짐/파일 특수문자

by 나비와꽃기린 2016. 8. 18.
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.


참고 소스 >>

http://iamreo.tistory.com/entry/Browser%EB%B3%84-file-name%EA%B9%A8%EC%A7%90%ED%98%84%EC%83%81

 

 

 

file 다운로드를 구현하던 도중 파일이름에 한글 또는 특수문자가 깨지는 현상이 발생했다.

이를 해결하기 위해 브라우저별 파일 이름 인코딩 작업을 진행하였다.


>>"파일다운로드"에 관련된 환경 및 구현 방법이 이쪽에 더 자세히 : http://mkil.tistory.com/224

 

(1) 다운로드 파일 소스 작성

아래 소스는 temp_fileNamedb에서 가져온 파일의 원본이름을 저장한 뒤,,,,,,,,,

ori_fileName에 브라우저체크 & 파일특수문자 처리를 한 최종 결과물인 파일이름을 저장시킨다.

 이때 ( getDisposition > 파일특수문자,  getBrowser > 브라우저체크 ) 이다.

그 후, 최종 파일이름인 ori_fileName을 가지고 stream을 통해 파일을 다운로드 한다


protected void renderMergedOutputModel(Map<String, Object> paramMap, HttpServletRequest request,
  HttpServletResponse response) throws Exception {

  File file = (File)paramMap.get("downloadFile");

  response.setContentType(getContentType());
  response.setContentLength((int)file.length());
   
  Map map =new HashMap();
  map.put("fileNm", file.getName() );
  String temp_fileName=fileService.getFileOrigNm( map );
  String ori_fileName = getDisposition(temp_fileName, getBrowser(request));
 
  response.setHeader("Content-Disposition", "attachment; filename=\"" + ori_fileName + "\";");
  response.setHeader("Content-Transfer-Encoding", "binary");
   
  OutputStream out = response.getOutputStream();
  FileInputStream fis = null;
   
  try {
	  fis = new FileInputStream(file);
	  FileCopyUtils.copy(fis, out);
  } catch(Exception e){
	  e.printStackTrace();
  }finally{
	  if(fis != null){
				 try{
							fis.close();
				 }catch(Exception e){}
	  }
  }
  out.flush();
}


(2) 브라우저 체크

필자가 testIE 버전은 11

브라우저의 User-Agent를 확인해보니 다음과 같았다.

Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko

따라서 MSIE return해 주지 않아 IE 테스트시 파일 이름이 제대로 인코딩 되지 않는

문제가 발생했었다.

임시방편으로 if (header.indexOf("Trident/7.0") > -1){ //IE 11 이상 을 추가해주었다.

(IE가 버전업이 되면서 token이 바뀐 것 같은데,, 이 방법이 일단 정확한 체크방법인지는 모르겠다 -_-;)


private String getBrowser(HttpServletRequest request) {
   String header = request.getHeader("User-Agent");
  
   if (header.indexOf("MSIE") > -1) {
		return "MSIE";
   } else if (header.indexOf("Chrome") > -1) {
		return "Chrome";
   } else if (header.indexOf("Opera") > -1) {
		return "Opera";
   } else if (header.indexOf("Trident/7.0") > -1){ //IE 11 이상
		//IE 버전 별 체크  >>  Trident/6.0(IE 10) , Trident/5.0(IE 9) , Trident/4.0(IE 8)
		return "MSIE";
   }
  
   return "Firefox";
}


(3)
파일명 특수문자 처리 


private String getDisposition(String filename, String browser) throws Exception {
          
   String encodedFilename = null;
   if (browser.equals("MSIE")) {
		encodedFilename = URLEncoder.encode(filename, "UTF-8").replaceAll("\\+", "%20");
   } else if (browser.equals("Firefox")) {
		encodedFilename = "\"" + new String(filename.getBytes("UTF-8"), "8859_1") + "\"";
   } else if (browser.equals("Opera")) {
		encodedFilename = "\"" + new String(filename.getBytes("UTF-8"), "8859_1") + "\"";
   } else if (browser.equals("Chrome")) {
	  StringBuffer sb = new StringBuffer();
	  for (int i = 0; i < filename.length(); i++) {
				  char c = filename.charAt(i);
				  if (c > '~') {
							 sb.append(URLEncoder.encode("" + c, "UTF-8"));
				  } else {
							 sb.append(c);
				  }
	  }
	  encodedFilename = sb.toString();
   } else {
	  throw new RuntimeException("Not supported browser");
   }
   return encodedFilename;
 
}


 

이상 파일 다운로드 끝이다다