오늘은 JSP / Servlet을 통한 웹 개발시 한글깨짐에 대해 처리하는 방법을 정리해 보았습니다.
웹 개발을 하다보면 GET / POST 방식의 전송시 한글이 깨지는 경우가 종종 있다.
특히 이제 막 웹 개발을 시작하는 분들의 경우 한글깨짐이 발생하여 굉장히 당황스러워 하는데, 사실 웹 개발자라면 초보시절에 한번쯤은 다들 경험해 봤을것이다.
이 한글깨짐을 해결하기 위해서는 일단 언어코드가 어떻게 바뀌어 왔는지 살짝만 살펴 보자.
컴퓨터에서 쓰는 영어코드는 ASCII 코드 이다. 7비트의 코드로 되어있다.
하지만 ACII 코드만 있는 것은 아니고 점점 다른 코드체계들이 나왔다.
한글 역시 마찬가지다.
조합형이니, 완성형이니, 확장완성형이니, 유니코드 한글형이니..뭐 잔뜩있다.
간단히 말하면조합형은 즉석에서 한글 자모를 조합해 한글을 표현한다. 예전 도스 시설에 많이 사용하였으나, 현재는 거의 쓰이지 않는다. 모든 한글 문자를 다 표현 할 수 있다는 장점이 있다.
완성형은 한글에서 많이 쓰이는 것들만 골라 미리 글자를 만들어 놓는다. 예를 들면, "가" "낙" 답" 이런식으로 말이다. 참... 문제가 많은 타입이지 않나 싶다. 윈도우95 까지 순수 완성형 한글을 썼다.
우리나라 표준에는 KSC5601 을 표준한글코드로 정의하고 있는데, 기본은 완성형 한글이고, 자모가 입력될 때 글자를 모은다음 코드테이블에서 코드를 찾아 치환한다. 메모리 낭비가 심하다는 단점이 있다.
확장 완성형한글은 기존의 완성형 한글에 "뺅" "잌" 같은 글자를 억지로 추가해 넣은 것이다. 윈도우98부터 현재버전까지 이놈을 쓴다.(내부적으로는 유니코드를 사용한다.)
유니코드는 한글 뿐 아니라 전세계 모든 언어를 모두 표현 할 수 있다. 한글을 표현 할때 확장 완성형보다 나은 점은, 코드가 순서대로 언어에 일관적으로 할당이 되어 있다는 거다. 조합형과 마찬가지로 모든 한글이 입력 가능하다.
자, 그럼 본론으로 돌아와서 왜 한글이 깨지는지 알아보자.
일단, 우리가 쓰는 한글 웹브라우져에서는 KSC5601 코드를 기본으로 사용한다.
그리고 웹으로 전송 할 때에는 x-www-form-urlencoded 형식으로 인코딩이 된다.
근데 이놈의 서블릿은(JSP도 마찬가지다. 어차피 서블릿으로 컴파일 되니깐) 우리의 훌륭하고 아름다운 한글을 개무시 하는 특성을 가지고 있다.
이 병신같은 서블릿님께서는 우리의 한글 코드 KSC5601 이 인코딩되어 전달되면, KSC5601이 왔다고 생각하지 않고 라틴어가 왔다고 생각한다. (라틴어 표준코드는 ISO-8859-1 이다) 그리고 JAVA 에서는 유니코드를 사용하므로 서블릿은 전달된 한글코드를 ISO-8859-1 형식으로 인코딩하게 된다.
이것은 명백하게 서블릿엔진 자체의 버그다. SUN 은 하루 바삐 이 버그를 고쳐 주기를 바란다.
아무튼 일단 웹->서블릿 으로 전달되는 과정에서 한글이 깨지게 된다.
1. JSP 페이지 1번 줄에 셋팅
<%@ page language= "java" contentType= "text/html; charset=utf-8" pageEncoding= "utf-8" %> |
2. post 방식의 파라미터를 받는 페이지마다 해당 라인 추가
request.setCharacterEncoding( "utf-8" ); |
3. 톰캣 server.xml 파일에 Connector마다 URIEncoding="utf-8" 추가
< connector redirectPort = "8443" protocol = "HTTP/1.1" port = "8080" connectionTimeout = "20000" URIEncoding = "utf-8" > </ connector > |
4. 톰캣 web.xml 파일 수정
< filter > < filter-name >setCharacterEncodingFilter</ filter-name > < filter-class >org.apache.catalina.filters.SetCharacterEncodingFilter</ filter-class > < init-param > < param-name >encoding</ param-name > < param-value >UTF-8</ param-value > </ init-param > < async-supported >true</ async-supported > </ filter >
|
처음 한번 경험하고 그 이후엔 그 경험을 토대로 더이상 실수하지 않도록 코딩합시다.