반응형

 

인터넷에 있던 글들을 정리한 것인데 한글 코드와 변환을 이해하는 데 도움이 되시길 바랍니다.

 

한글 코드 체계

 

ASCII : 7비트 코드

ASCII 확장: 8비트 코드

조합형: 2바이트 코드

완성형(KSC5601): 2바이트 코드   = euc-kr

확장 완성형: 2바이트 코드, 윈도우98부터 사용 (윈도우 내부적으로는 유니코드 체계)

 

웹에서 한글이 깨지는 이유?

 

순수 웹

 

'*.jsp'가 아닌 순수 HTML(*.html or *.htm) 파일일 경우, 아래처럼 HTML meta 태그를 이용한다. (default) 

<meta http-equiv="Content-Type" content="text/html;charset=euc-kr"> 

만일, OS(웹서버 말고) Win2k일 경우는 마지막의 'charset=euc-kr' 대신에 'ksc-5601'로 지정한다

<meta http-equiv="Content-Type" content="text/html;charset=ksc5601"> 

 

 

à 서블릿

 

한글 웹브라우저: KSC5601 기본 사용

웹 전송 시: x-www-form-urlencoded 형식으로 인코딩 됨

서블릿(JSP 포함)은 전달된 한글 코드를 ISO-8859-1 (라틴어) 형식으로 인코딩 시도

자바는 유니코드 사용하므로 한글 코드를 ISO-8859-1 형식으로 인코딩  ß 버그!!!

 

*결과적으로 웹 -> 서블릿 전달 과정에서 한글 깨져버림

 

깨진 한글을 제대로 된 한글을 보려면

ISO-8859-1 형식의 유니코드로 된 것을 다시 ISO-8859-1의 바이트 배열로 추출

원래 포맷인 KSC5601로 변환

 

 

서블릿 à

 

이 때도 한글을 보내면 ISO-8859-1 형식으로 변환한다.

그러므로 한글 코드는 KSC5601을 사용하고 영어는 JSC5636을 사용하는 euc-kr로 변환해서 전송해야 한다. (euc-kr = Extended UNIX Korea Code )

해결 방법은 JSP나 서블릿에서 contentTypecharset“euc-kr”로 설정하는 것이다.

<%@ page contentType="text/html; Charset=EUC-KR" %>

 

: "EUC-KR" 또는 "EUC_KR" 또는 "euc-kr" 상관없다.

 

웹 페이지에서 텍스트 필드에서 입력 받아 올 때 request.getParameter()로 받아오면 100% 깨졌다고 생각하면 된다. 복구하려면 다음처럼 한다.

str.getBytes(“8859_1”) 메소드로 8859_1 타입의 바이트 배열로 추출하고 코드를 변환하여 저장한다. 아래처럼 특정 charset 사용하여 바이트 배열을 디코딩 생성한다.

new String(str.getBytes(“8859_1”);      

 

이걸 메소드로 다시 구현해서 사용해보자.

 

public static String toKOR(String s){   // to KSC5601

if (s==null) {

return null;

}

Try {

return new String(s.getBytes("8859_1"),"KSC5601");

} catch(Exception e) {return s;}

}

 

 

DB –

 

DB JSP(JAVA)가 사용하는 코드체계가 다르기 때문에 한글처리문제가 발생하는데 일반적으로 DB ASCII KSC5601 코드체계를 사용하고 JSP(JAVA)는 유니코드를 사용하기 때문이다. 우선은 JSP 지시문에서 page 지시어에 속성으로 Charset을 한글코드("EUC-KR")로 정의한다.

 

<%@ page contentType="text/html; Charset=EUC-KR" %>

 

그 다음엔 JSP 페이지에서 브라우저로 한글을 출력할 때에는 KSC5601(또는 "EUC-KR")로 변환하고, 반대로 한글 정보를 DB로 저장할 경우에는 "8859_1" 코드로 변경하면 안전하다.

 

<%

String str="안녕하세요";

// 브라우저에 한글을 출력하기 전에 먼저 변환해 줌

str = new String(str.getBytes("8859_1"), "KSC5601");

out.println(str);

...

// 파일이나 DB에 한글을 저장할 때 먼저 아래처럼 변환해 줌

str = new String(str.getBytes("KSC5601"), "8859_1");

%>

 

 

Tomcat에서 한글 처리

 

Tomcat 버전 3.0 이하는 값이 넘어 올 때 Cp1252로 넘어오므로 다음처럼 처리한다
String name = new String(request.getParameter("name".getBytes("Cp1252"),"EUC_KR"); 

Tomcat
버전 3.1 이상인 8859_1로 넘어오므로 다음처럼 처리합니다.
String name = new String(request.getParameter("name".getBytes("8859_1"),"EUC_KR"); 

 

JSP 지시문에서 page 지시어에 속성으로 Charset "EUC-KR"로 정의한다.

 

<%@ page contentType="text/html; Charset=EUC-KR" %>

(소문: euc-kr 대신에 'MS949'(대문자) 쓰는 것이 좋단다. )

 

2. Tomcat Get이나 POST 전송 값이 Cp1252 변환되므로 request.getParameter() 메소드를 사용할 때는 반드시 "EUC-KR"로 변환해야 한다.

 

<%

String name;

name=new String(request.getParameter("name").getBytes("Cp1252"), "EUC-KR");

%>

 

// 유니코드를 한글 코드로

protected String uni2ksc (String Unicodestr) throws UnsupportedEncodingException

{

return new String (Unicodestr.getBytes("8859_1"),"KSC5601");

}

 

// 한글 코드를 유니코드로

protected String ksc2uni(String str) throws UnsupportedEncodingException

{

return new String( str.getBytes("KSC5601"), "8859_1");

}

 

참고:  http://www.senun.com/Left/Programming/Java/Jsp/jsp_syntax_hangul.htm

 

 

그래서 한글이 정상적으로 처리되려면

1,
브라우저 -- 8859_1(default) à JSP 컨테이너(JSP/JAVA) -- 8859_1(default) à 브라우저
(*
비추전)

2.
브라우저 -- euc-kr(요청시 브라우저에서 지정하던지 setCharacterEncoding 사용 à
JSP
컨테이너(JSP/JAVA) -- euc-kr(response에서 contentType으로 지정) à 브라우저
(*
추전)

 

 

MySQL 연결

 

DB 저장시 한글 저장 문제가 발생하는 이유는 DB Server JSP 사용하는 코드 체제가 다르기 때문입니다. DB 일반적으로 ASCII ksc5601코드 체계를 사용하고 JSP Unicode 사용합니다.

 

mysql의 연결 urlUnicode 옵션을 주고 문자셋을 주면 그냥 됩니다.

 

jdbc:mysql://localhost/디비명?useUnicode=true&characterEncoding=euc-kr

 

 

Resin

 

<font color=red>Resin</font> 경우는 euc-kr 아니라

<font color=red>ksc5601</font>임에 유의하자

 

 

 

getByte() 메소드 자세히 알기 
============================ 


형식; getByte(String enc) 

(1)
정의; String을 매개변수로 주어지는 charset으로 변환
(2)
매개변수; US-ASCII, ISO-8859-1, UTF-8, UTF-16BE, UTF-16LE, UTF-16 
(3)
리턴; byte[] 
(4)
예외상황; exceptionUnsupportedEncodingException 
   
exception 'java.io.*' import해야 사용가능하다

 

 

Unicode Unicode(UTF-8)

 

Unicode는 코드페이지 1200이며, Unicode(UTF-8) 65001입니다.
그 크기 또한 다릅니다. (하늘과 땅 차이 -_-)

- Unicode
Unicode(UTF-8)을 간단 정리


Unicode
는 모든 문자를 2Byte로 표시한다. - ISO-2022 형태의 다국어와 차이점.
(
영문이고 다국어고 필요없다. 어떤 언어든 65536가지를 표현 가능하다

이 뜻은 2Byte가 어떤 형태로 구성되는지를 알 수 있게 하는 말.)

UTF-8
은 기존 ASCII 1xx까지 유지하며 다국어는 2~3Byte로 표시한다

(, 영문은 1Byte처리 - 아래에서 다시 설명하기 때문에 매우 중요)

 

UTF-8은 한글이 순차 배열이기에 정렬에 좋습니다. (Unicode와의 비교를 제외한다면)

그에 비해 KSC5601(KSC5601-1992)는 정렬 속도가 떨어집니다. (공포의 8822)

 

 

문서의 문자코드 자동 구분?

 

시작을 16진수로 FF FE로 시작하는 문서는 Unicode를 사용합니다.

또한 Unicode(UTF-8)는 서명 있는 Unicode(UTF-8) 문서일 경우는 대부분 가능합니다.

만약 서명이 있는 경우라면 EF BB BF로 시작합니다. 그래서 각종 Tool에서 자동으로 읽을 수 있는 것입니다.

 

 

MS-949, windows-949

 

MS949는 엄밀히 "KSC5601-1987"이거나 "KSC5601-1992" 입니다.

1992 1987를 모두 포함하고 문자 위치까지 호환됩니다

19921987에 추가된 문자 8822(공포의)개가 있다는 차이가 있습니다. (MS OS에서는 단순한 폰트 차이 정도)

그래서 일반적으로 KSC5601라고 통합하여 사용하는 것입니다

엄밀히 따지면 MS949 META TAG에서 windows-949 혹은 ks_c_5601-1987에 해당합니다.

 

<이상>

 

반응형

+ Recent posts