많은 분들이 jsp에서 한글처리때문에 많은 고생을 하고 계신데 한글처리는
동작원리만 알면 쉽게 풀수 있는 문제입니다.
그럼. 동작원리를 잠깐 알아볼까요.... ^^
먼저 자바는 유니코드를 사용한다는 사실을 인지해야합니다.
(자바하시는 분들은 다 알고 있지만 한글처리를 하실때 많이 빼먹는 부분이기도합니다)
다시 말해서 jsp(java) 안에서는 문자열이 유니코드라는 것입니다.
그럼. 브라우저에서 request를 보낼 때 입니다.
HTTP 요청은 8859_1로 보냅니다. 즉 다시 말하면 한글완성형코드 그대로 변환없이
보냅니다. (byte그대로...)
일단 간략하게 그리면
브라우저 한글완성형코드 그대로 전송 --request(*)--> jsp 컨테이너에서 유니코드로 변환 --> 내부처리
--response(*)--> 결과물을 브라우저로 전송
(*)부분에서 유니코드<-->해당문자열코드로 변환이 일어납니다.
request(*)에서 문자셋이 지정되어 있지 않으면 (이 말은 브라우저가 request를 요청할 때 특별히
문자셋을 지정하지 않았을 때, 가장 일반적인 상황입니다) 8859_1로 처리됩니다.
즉. "한"이라는 문자열을 보냈다고 했을 때 완성형코드 2byte가 그대로 전송되죠.
8859_1 문자셋코드를 유니코드로 변환하면 상위바이트와 하위바이트가 각각 1자의
유니코드로 변환되므로 "한"이라는 글자는 유니코드 2자로 변환됩니다.
아시다시피 유니코드에서 한글은 1자입니다. 이 변환이 있더라도 한글byte가 깨지지는 않습니다.
왜냐하면 상위, 하위바이트가 각각 유니코드 안에 그대로 살아있기때문입니다.
이 경우 유니코드문자열.getBytes("8859_1")의 메소드 호출로 원래 byte열로 돌릴 수 있기 때문입니다.
request에서 기본 8859_1 문자셋을 다른 문자셋으로 바꾸는 메소드가 있죠.
request.setCharacterEncoding("euc-kr") 이라고 하면(반드시 파라미터를 읽기 이전에 해야합니다)
한글 1자(2byte)를 유니코드 1자로 변환해줍니다..
response(*) 부분은 브라우저에 보내기전에 유니코드를 해당 문자셋의 byte열로 변환하는 부분입니다.
page 태그나 response.setContentType() 메소드에서 "text/html; charset=euc-kr" 식으로 설정가능합니다.
지정하지 않으면 역시 8859_1로 처리되므로 request에서 8859_1이면 들어온 그대로 다시 보내므로
어떤 문자코드라도 깨지지 않습니다. 그러나 euc-kr로 되어 있으면 유니코드 --> 한글완성형
변환시 유니코드 1자를 한글 1자로 인식하기때문에 한글유니코드는 2byte의 완성형 코드로 변환됩니다.
여기서 한글유니코드를 8859_1으로 변환하면 유니코드의 상위byte가 없어지고 하위byte만 사용됩니다.
그러니 한글이 깨져서 브라우저로 전송됩니다.
이 경우 글자의 상위byte가 없어지므로 되돌릴 수 없습니다.
그래서 한글이 정상적으로 처리될려면
1, 브라우저 -- 8859_1(default) --> jsp 컨테이너(jsp/java) -- 8859_1(default) --> 브라우저
(* 비추전)
2. 브라우저 -- euc-kr(요청시 브라우저에서 지정하던지, 아니면 setCharacterEncoding사용 -->
jsp 컨테이너(jsp/java) -- euc-kr(response에서 contentType으로 지정) --> 브라우저
(* 추전)
3. jsp 내에서 <jsp:include>(실행시간include)로 jsp가 아닌 한글화일(html등) 포함할 때는 jsp컨테이너가 실행될 때
시스템 문자셋에 따라서 변환이 됩니다.
그래서 1의 경우일 경우 시스템은 반드시 8859_1로 문자셋(로케일의 문자코드셋)으로 되어야하고
2의 경우는 한글코드(리눅스, 원도우즈에 따라 명칭이 다르지만 기본적으로 완성형표준코드입니다)로
지정되어 있어야 깨지지 않습니다.
4. 자바빈이나 db에서 한글처리 1의 경우를 비추천으로 하는 이유는 자바빈이나 db에서도
모두 8859_1로 맞추어 주어야한다는 것입니다. 즉 클래스를 컴파일할 때도 컴파일 옵션에 8859_1로
지정해주어야 클래스안의 한글이 깨지지 않습니다. (디폴트로 시스템 문자셋으로 컴파일, 원도는 당근 한글셋)
2의 경우는 euc-kr로 맞추어 주어야합니다. 대부분 개발시스템의 문자셋은 당근 한글이겠죠 ^^
2의 경우에서 mysql의 연결url에 unicode사용 옵션을 주고 문자셋을 주면 그냥 됩니다.
(상세한 옵션: jdbc:mysql://localhost/디비명?useUnicode=true&characterEncoding=euc-kr)
오라클도 시스템 문자셋에 따라 알아서 동작하는데
db가 asc7인가(갑자기 기억안남) 일때 문제가 있는 경우가 있는데 이경우 오라클 클라이언트를
같이 맞추어주고 getString(...)메소드를 읽을 때 new String(XXX.getBytes(8859_1), "euc-kr")로
변환해주어야 합니다. 이건 오라클 jdbc드라이버가 db asc7 --> client euc-kr 변환을 못해주는 것 같습니다.
asc7 --> 8859_1 --> euc-kr 요렇게 두번 해주어야 하는데 asc7 --> euc-kr 요렇게 바로 해버리니까
한글이 깨지는 것 같습니다.(오라클 jdbc 스펙을 확인해보세요..)
동작원리만 알면 쉽게 풀수 있는 문제입니다.
그럼. 동작원리를 잠깐 알아볼까요.... ^^
먼저 자바는 유니코드를 사용한다는 사실을 인지해야합니다.
(자바하시는 분들은 다 알고 있지만 한글처리를 하실때 많이 빼먹는 부분이기도합니다)
다시 말해서 jsp(java) 안에서는 문자열이 유니코드라는 것입니다.
그럼. 브라우저에서 request를 보낼 때 입니다.
HTTP 요청은 8859_1로 보냅니다. 즉 다시 말하면 한글완성형코드 그대로 변환없이
보냅니다. (byte그대로...)
일단 간략하게 그리면
브라우저 한글완성형코드 그대로 전송 --request(*)--> jsp 컨테이너에서 유니코드로 변환 --> 내부처리
--response(*)--> 결과물을 브라우저로 전송
(*)부분에서 유니코드<-->해당문자열코드로 변환이 일어납니다.
request(*)에서 문자셋이 지정되어 있지 않으면 (이 말은 브라우저가 request를 요청할 때 특별히
문자셋을 지정하지 않았을 때, 가장 일반적인 상황입니다) 8859_1로 처리됩니다.
즉. "한"이라는 문자열을 보냈다고 했을 때 완성형코드 2byte가 그대로 전송되죠.
8859_1 문자셋코드를 유니코드로 변환하면 상위바이트와 하위바이트가 각각 1자의
유니코드로 변환되므로 "한"이라는 글자는 유니코드 2자로 변환됩니다.
아시다시피 유니코드에서 한글은 1자입니다. 이 변환이 있더라도 한글byte가 깨지지는 않습니다.
왜냐하면 상위, 하위바이트가 각각 유니코드 안에 그대로 살아있기때문입니다.
이 경우 유니코드문자열.getBytes("8859_1")의 메소드 호출로 원래 byte열로 돌릴 수 있기 때문입니다.
request에서 기본 8859_1 문자셋을 다른 문자셋으로 바꾸는 메소드가 있죠.
request.setCharacterEncoding("euc-kr") 이라고 하면(반드시 파라미터를 읽기 이전에 해야합니다)
한글 1자(2byte)를 유니코드 1자로 변환해줍니다..
response(*) 부분은 브라우저에 보내기전에 유니코드를 해당 문자셋의 byte열로 변환하는 부분입니다.
page 태그나 response.setContentType() 메소드에서 "text/html; charset=euc-kr" 식으로 설정가능합니다.
지정하지 않으면 역시 8859_1로 처리되므로 request에서 8859_1이면 들어온 그대로 다시 보내므로
어떤 문자코드라도 깨지지 않습니다. 그러나 euc-kr로 되어 있으면 유니코드 --> 한글완성형
변환시 유니코드 1자를 한글 1자로 인식하기때문에 한글유니코드는 2byte의 완성형 코드로 변환됩니다.
여기서 한글유니코드를 8859_1으로 변환하면 유니코드의 상위byte가 없어지고 하위byte만 사용됩니다.
그러니 한글이 깨져서 브라우저로 전송됩니다.
이 경우 글자의 상위byte가 없어지므로 되돌릴 수 없습니다.
그래서 한글이 정상적으로 처리될려면
1, 브라우저 -- 8859_1(default) --> jsp 컨테이너(jsp/java) -- 8859_1(default) --> 브라우저
(* 비추전)
2. 브라우저 -- euc-kr(요청시 브라우저에서 지정하던지, 아니면 setCharacterEncoding사용 -->
jsp 컨테이너(jsp/java) -- euc-kr(response에서 contentType으로 지정) --> 브라우저
(* 추전)
3. jsp 내에서 <jsp:include>(실행시간include)로 jsp가 아닌 한글화일(html등) 포함할 때는 jsp컨테이너가 실행될 때
시스템 문자셋에 따라서 변환이 됩니다.
그래서 1의 경우일 경우 시스템은 반드시 8859_1로 문자셋(로케일의 문자코드셋)으로 되어야하고
2의 경우는 한글코드(리눅스, 원도우즈에 따라 명칭이 다르지만 기본적으로 완성형표준코드입니다)로
지정되어 있어야 깨지지 않습니다.
4. 자바빈이나 db에서 한글처리 1의 경우를 비추천으로 하는 이유는 자바빈이나 db에서도
모두 8859_1로 맞추어 주어야한다는 것입니다. 즉 클래스를 컴파일할 때도 컴파일 옵션에 8859_1로
지정해주어야 클래스안의 한글이 깨지지 않습니다. (디폴트로 시스템 문자셋으로 컴파일, 원도는 당근 한글셋)
2의 경우는 euc-kr로 맞추어 주어야합니다. 대부분 개발시스템의 문자셋은 당근 한글이겠죠 ^^
2의 경우에서 mysql의 연결url에 unicode사용 옵션을 주고 문자셋을 주면 그냥 됩니다.
(상세한 옵션: jdbc:mysql://localhost/디비명?useUnicode=true&characterEncoding=euc-kr)
오라클도 시스템 문자셋에 따라 알아서 동작하는데
db가 asc7인가(갑자기 기억안남) 일때 문제가 있는 경우가 있는데 이경우 오라클 클라이언트를
같이 맞추어주고 getString(...)메소드를 읽을 때 new String(XXX.getBytes(8859_1), "euc-kr")로
변환해주어야 합니다. 이건 오라클 jdbc드라이버가 db asc7 --> client euc-kr 변환을 못해주는 것 같습니다.
asc7 --> 8859_1 --> euc-kr 요렇게 두번 해주어야 하는데 asc7 --> euc-kr 요렇게 바로 해버리니까
한글이 깨지는 것 같습니다.(오라클 jdbc 스펙을 확인해보세요..)
댓글 0
번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
---|---|---|---|---|
38 | orion와 eclipse을 이용하여 EJB개발시 참고(내부개발용) | 박상현 | 2004.06.22 | 2442 |
37 | 주소 감추기 | 박상현 | 2004.06.13 | 1955 |
36 | javascript: event,this는 사용할 수 없습니다 | 박상현 | 2004.06.13 | 1765 |
35 | 점선없애기 | 박상현 | 2004.06.13 | 1973 |
34 | <table></table>을 스크롤 시키기 | 박상현 | 2004.04.09 | 1758 |
33 | td및 tr의 위치 알아내기 | 박상현 | 2004.01.31 | 2751 |
32 | 자바스크립트 펑션 및 변수 공유 | 박상현 | 2004.01.07 | 2337 |
31 | 스크롤바를 따라다니는 메뉴판 | 박상현 | 2003.12.04 | 1575 |
30 | 스크롤바를 따라다니는 이미지 | 박상현 | 2003.12.04 | 1684 |
29 | 이벤트 종류알기 및 좌표 읽기 | 박상현 | 2003.12.03 | 1989 |
28 | 문서크기에 맞게 아이프레임폭 자동으로 조정하기 | 박상현 | 2003.11.17 | 1928 |
27 | 목록에서 선택된 라인에만 색칠하고 다른것은 이전색으로 변경하기 | 박상현 | 2003.11.13 | 1705 |
26 | 목록에서 다중 선택된 항목을 표시(특정색상)하고 체크박스를 선택해주는 스크립트 | 박상현 | 2003.11.07 | 2837 |
25 | 여러가지의 색으로 롤오버 효과및 항목을 선택시 선택된 색을 고정시키는 예제 | 박상현 | 2003.11.07 | 2212 |
24 | 쇼핑몰에 포함될 기능(참고) | 박상현 | 2003.11.06 | 1624 |
» | 한글처리 방법/절차 이해 | 박상현 | 2003.10.20 | 1930 |
22 | event.keyCode의 숫자표 | 박상현 | 2003.10.20 | 1863 |
21 | jsp페이지에서 popup창의 depth에 따른 메인 복귀 방법 달리하기... | 박상현 | 2003.10.14 | 3496 |
20 | 배포하기(Cab 파일 작성법) | 박상현 | 2003.10.13 | 2580 |
19 | 정수값을 3자리수마다 컴마를 찍기 | 박상현 | 2003.10.13 | 2177 |