웹을 하다보면 항상 문제가되는게 바로 한글이다...
특히 무시할수 없는게 브라우져(Browser) 종류가 많으니...
요즘엔 EUC-KR 대신 UTF-8 을 많이 쓰니 웹페이지에서 한글이 깨지는 경우는 줄었는데
역시나 문제가 생기긴 한다...
특히 IE가 제일 말성...
IE 11 은 Agent 이름을 바꾸질 않나...
그외에는 OS 특성상 맥과 윈도우 인코딩 차이로
한글자소 분리되는 케이스가 있는데
일단은 브라우져를 확인하고
파일 다운로드 시 한글을 처리하는걸 해볼까 한다
이번에 Edge 브라우져에서 문제가 되기도 했고...
HTTP Request 헤더의 User-Agent를 확인하는 방법
public String getBrowser(HttpServletRequest req) {
String userAgent = req.getHeader("User-Agent");
if(userAgent.indexOf("MSIE") > -1
|| userAgent.indexOf("Trident") > -1 //IE11
|| userAgent.indexOf("Edge") > -1) {
return "MSIE";
} else if(userAgent.indexOf("Chrome") > -1) {
return "Chrome";
} else if(userAgent.indexOf("Opera") > -1) {
return "Opera";
} else if(userAgent.indexOf("Safari") > -1) {
return "Safari";
} else if(userAgent.indexOf("Firefox") > -1){
return "Firefox";
} else{
return null;
}
}
참고로 User-Agent를 보내지 않거나 속이는 경우에는 null을 반환한다
문자열 검출을 위해 indexOf를 사용했는데 contains을 사용해도 된다
Edge는 User-Agent 를 보면 Chrome, Safari 가 섞여있다....
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14931 |
그래서 Edge를 우선 확인해야한다
public String getFileNm(String browser, String fileNm){
String reFileNm = null;
try {
if (browser.equals("MSIE") ||
browser.equals("Trident") ||
browser.equals("Edge")) {
reFileNm = URLEncoder.encode(fileNm, "UTF-8").replaceAll("\\+", "%20");
} else {
if(browser.equals("Chrome")){
StringBuffer sb = new StringBuffer();
for (int i = 0; i < fileNm.length(); i++) {
char c = fileNm.charAt(i);
if (c > '~') {
sb.append(URLEncoder.encode(Character.toString(c), "UTF-8"));
} else {
sb.append(c);
}
} reFileNm = sb.toString();
} else{
reFileNm = new String(fileNm.getBytes("UTF-8"), "ISO-8859-1");
}
if(browser.equals("Safari") || browser.equals("Firefox"))
reFileNm = URLDecoder.decode(reFileNm);
}
} catch(Exception e){}
return reFileNm;
}
MS IE/Edge 일 경우 URLEncoder를 사용한게 눈에 띄는데
간혹 %로 시작하는 파일을 다운받는 사이트들이 있는데
IE처리만 해놔서 그런듯 하다
사실 Chrome 일경우 별도로 처리가 되어있긴한데
new String(fileNm.getBytes("UTF-8"), "ISO-8859-1"); 처리만 해줘도 딱히 문제는 없었다
String fileNm = "한글 파일명";
String browser = getBrowser(req);
res.setContentType("application/octet-stream; charset=UTF-8");
res.setHeader("Content-Description", "file download");
res.setHeader("Content-Disposition", "attachment; filename=\"".concat(getFileNm(browser, fileNm)).concat("\""));
res.setHeader("Content-Transfer-Encoding", "binary");
다운로드 부분중 response 부분만 요약 해놨다
좀더 간지나게 처리하려면 MIME-type 공부를 해야겠지만 다음기회에...
추가적으로..
맥에서 사파리로 네이버 카페 파일을 받는경우 알수없는 문자로 다운되는데
파일명을 ISO-8859-1로 읽어서 UTF-8로 변환하면 된다
뭐 네이버에서 일하는게 아니니 크게 관심은 없지만
내가 파일을 받았을때가 문제가 된다...
참고
User-Agent: https://developers.whatismybrowser.com/useragents/explore/software_name/
MIME-type: https://developer.mozilla.org/ko/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types
JAVA 자바 Map, HashMap, EgovMap 값 확인하기 (0) | 2021.01.19 |
---|---|
JSP/SERVELT HTML Character Entity 특수문자 치환 StringEscapeUtils & 처리 (0) | 2019.11.30 |
JSTL문법 <c:forEach> c:tag를 이용한 리스트 출력 (0) | 2018.01.01 |
JSTL문법 <c:forTokens> c:tag 를 이용한 리스트 정렬기능 구현 (0) | 2018.01.01 |
JAVA 자바 Mysql Load Data Infile (0) | 2016.09.20 |
댓글 영역