코드 변환, 유니코드 한글, 서브릿, 데이타베이스


[ 다음 글들 ] [ 이어서 글올리기(답하기) ] [ 자바 묻고 답하기 ]

글쓴이 :김덕태 1998년 1월 14일 17:43:20

In Reply to: 김덕태님 참고하세요... posted by 김필호 on 1998년 1월 13일 11:17:51:

1. toDB와 convert_to_ascii()의 차이점.
물론, 이 두가지는 코드만을 보면 거의 같다고 볼 수 있으며,
말씀하신 해결 방안과도 동일합니다.
하지만, 몇가지 미묘한 차이가 있습니다.
가장, 중요한 순으로 열거하면,


- toDB는 메쏘드의 의미상 데이타베이스에 접근 할때 코드 변환을
교정한다는 의미가 있는 데, convert_to_ascii()는 8859_1로만
무조건 변환한다는 의미가 있습니다.
만약, JDBC 드라이버가 8859_1 인코딩으로 코드 변환하는 것이
아니라 다른 인코딩으로 변환하거나 혹은 제대로 코드 변환하는
드라이버로 바뀐후, 동일한 자바 프로그램을 실행시키기 위해서는
convert_to_ascii() 메쏘드를 사용한 부분을 전부 수정해야 합니다.
그러나, JDBC 드라이버의 목적이 데이타베이스 접근 프로그램을
한번만 작성해서 어떠한 데이타베이스에도 접근할 수 있도록
한다는 목적과 상치하게 됩니다.

- 물론, 이럴 때, convert_to_ascii() 메쏘드의 몸체를 변경해서
해결할 수 있습니다. 그러나, 8859_1 인코딩으로 변환하지 않으면서
convert_to_asccii() 메쏘드 이름을 원시 화일 곳곳에 남겨둔다면
의미가 맞지 않는 프로그램이 되어 버그 가능성이 높아집니다.
또한, 데이타베이스를 접근하지 않는 부분에서도 그러한
메쏘드를 사용할 필요가 있는 데, 그 부분에서도 convert_to_ascii()
메쏘드 이름을 사용하고 있으므로, 메쏘드의 몸체를 함부로
바꾸지도 못하게 되는 문제가 생깁니다.


- toDB는 UnsupportedEncodingException은 예외를 제거하지 않고
상승전파시킵니다. 그러한 예외가 발생했음에도 불구하고
프로그램이 계속 진행되는 것은 (비록, 메시지를 출력하기는 하나,
일반 사용자는 자바 콘솔에 출력되는 메시지에대해서 잘 모를것입니다.)
바람직하지 않다고 생각되어 저는 예외를 상승 전파시켜
프로그램의 윗부분 코드에서 이 예외를 처리토록 한 것입니다.
대개의 경우는 적절한 형태로 오류 메시지를 출력하고
프로그램을 중단시킬 것입니다.
물론, 예외가 상승 전파되는 호출측에서 이를 처리해야되니깐
좀 귀찮기는 하겠지만 지금 큰 문제라고 생각되는
OutputStreamWriter, CharToByteKSC5601 클래스의 버그는
바로 예외처리를 제대로 하지 않아서 생기는 문제입니다.


- convert_to_ascii()는 메쏘드 이름이 너무 깁니다.
좀 커다란 데이타베이스 접근 프로그램을 짠다면
곳곳에서 이 메쏘드를 호출해야 하기 때문입니다.



2. remove... 메쏘드에 대해서.


remove... 메쏘드가 필요없다고 한 것은, 그런 방향의 해결방안이
필요없다는 것이 아니고, getBytes("8859_1")이라는 간단한
메쏘드가 이미 있기 때문에 필요없다고 한 것입니다.


3. 데이타베이스에 저장되는 코드값.
유니코드의 코드값이 직접 데이타베이스에 저장되는 일은
거의 없을 것입니다. 유니코드는 주로 내부 표현에 적합하기
때문입니다.
데이타베이스에 모든 유니코드 문자를 저장할려면 유니코드와
등가변환할 수 있는 UTF8 인코딩을 사용해서 저장하게 됩니다.


아직은 UTF8 인코딩을 제대로 보여주거나 다룰 수 있는 시스템 환경 및
프로그램이 부족하므로, 대부분의 데이타베이스에서 KSC5601 인코딩으로
저장하게 될 것입니다.
따라서, 데이타베이스에 저장될 때는 자바에서 만들어진 유니코드 문자열을
UTF8, KSC5601, 8859_1등의 특정 외부 인코딩으로 반드시 변환하여
저장되게 마련이고, 이러한 작업을 JDBC 드라이버가 담당합니다.

4. 유니코드 코드값으로 저장되지 않는 데, 어떻게
유니코드 한글이 웹브라우저에서 보이는 가?


윈도우즈에서 KSC5601에 없는 한글이 보이는 이유는 마이크로소프트가
나름대로 KSC5601에 새로운 코드값을 할당해서 한글을 보이게 한것입니다.
이걸 확장 완성형이라고 하는 것 같은 데, 하여튼 기존의 KSC5601 코드값은
변경시키지 않았습니다. 한마디로 누더기식 확장인데, 때문에 이는 표준으로 채태되지
않았으며, 유닉스등에서도 볼 수 없고, 앞으로도 지원하는 시스템, 프로그램이
늘어날 가능성이 없습니다. 자바에서 만약 그런 확장 영역의 문자를 사용하려
한다면 유니코드의 한글 코드값으로 변환하여야 하는 데, 그렇게 할 수가 없습니다.
표준 인코딩이 아니기에 코드 변환 클래스가 없기 때문입니다.
그렇다고 해서 그 인코딩을 전혀 쓸 수 없는 것은 아니나, 문제는
그 인코딩을 사용할 수 있는 방법이 극히 제한됩니다.
김필호님께서 써브릿으로 그 유니코드값을 출력하셨는데,
그런 상황에는 사용할 수 있습니다.
하지만 다른 상황에서도 응용해서 사용할려고 하면
상당한 어려움이 따르게 됩니다.


코드 변환을 잘못하면 정보의 손실, 왜곡등의 문제를 발생시키나
어떻게 보면 숫자 놀음의 특징을 갖고 있습니다.
즉, 한글을 반쪽씩 쪼개서 마치 유니코드내의 8859_1 문자인 것처럼 처리하면
정보의 손실없이도 데이타베이스의 8859_1 인코딩을 가장하여
저장하고 복구할 수 있습니다.
단, 이때에는 유니코드의 한글 영역의 코드값이 아니므로,
사용이 상당히 제한되게 됩니다.


김필호님의 데이타베이스로부터 서블릿 출력과정까지 보면,
한글이 유니코드 한글 코드값으로 저장된 것이 아닙니다.


우선, 유니코드 한글로 표현되고, 상위 바이트가 0이 붙은
확장 완성형을 저장하셨으며, 사용하신 JDBC 드라이버는
상위 바이트 0을 떼어낸 코드값을 데이타베이스에 저장하신 것입니다.
다시 JDBC 드라이버로부터 데이타값을 꺼내오면
상위 바이트 0을 붙여 유니코드를 만들고,
ServletOutputStream의 println을 사용하여 출력하면
이 메쏘드는 또다시 0을 떼어냅니다.

결국, 데이타베이스의 입력에서부터 출력까지 계속 일관되게 바이트 0만 붙었다
떼었다 했을 뿐이므로 정보의 손실은 없고, 한글 스트링은
정상적인 한글 스트링이 아니며, 본래의 확장 완성형 코드값도
그대로 복구되어 출력된 것이며,
윈도우즈의 웹브라우저에서는 확장 완성형코드를 출력하면
브라우저는 해당 폰트를 찾아 KSC5601에 없는 한글을
출력해준 것입니다.



5. KSC5601에 없는 유니코드 한글을 저장, 출력할 수 있는 방법.


KSC5601에 없는 유니코드를 저장, 출력하는 표준적인 방법은
모든 유니코드 문자를 표현할 수 있으며 호환성에 문제를
덜 일으키지 UTF8 인코딩이며, UTF8 인코딩은 한글만을
포함하는 것이 아니라서, 굳이 한글 환경이 아니더라도
시스템의 지원을 받을 수 있는 인코딩이며, 실제로 데이타베이스,
운영체제등의 지원이 늘어나고 있습니다.
자바에서는 UTF8 인코딩과 유니코드와의 코드 변환을
제공하며, 자바 그래픽 프로그램을 작성한다면 윈도우즈
환경에서는 모든 유니코드 한글을 출력할 수 있습니다.
이는 자바소프트의 SymbolTest라는 데모 프로그램을 수정한

http://calab.kaist.ac.kr/~dtkim/java/example/i18n/CodeDisplay.html
를
방문하신 후, `출력코드범위'에서 `현대 한글 음절'을 선택하시면
모든 현대 한글을 출력시킬 수 있음을 알 수 있으며,
그와 같이 출력하려면, 유니코드의 한글 영역으로 제대로
표현된 코드값을 같는 char[]나 String이어야만 합니다.


6. 자바 1.2와 JDBC의 문제.
자바 1.2 beta spec을 뒤져 보니, 자바 1.1에서의 I18N 지원 누락 문제는
제가 지적한 해결방안중 2번 방법으로 나가고 있는 듯합니다.
즉, JDBC 드라이버가 변환할 인코딩을 자바 프로그램에서 지정할 수
있게 하는 것입니다. ("KSC5601"이든 "UTF8" 이든)


7. 자바 1.1에서 어떻게 UTF8로 저장하는 가?
8859_1 인코딩으로 변환하는 드라이버에서는
toDB, fromDB에서 "KSC5601" 대신, "UTF8"로 바꾸어주면
데이타베이스에는 "UTF8" 인코딩으로 저장됩니다.
(따라서, 모든 유니코드 한글이 정보의 손실이 없이
저장됨)
단, 문제는 8859_1 인코딩으로 인코딩하지 않는 드라이버가
있다는 것입니다.
이때문에, JDBC 드라이버의 I18N 지원을 위한 표준화된 기능
(자바 1.2에서 추가된 기능같은 것)이 필요합니다.


8. 자바 1.1에서의 최적의 JDBC 해결 방안.
8859_1 인코딩으로 변환하지 않는 드라이버들을 찾아내서
하나의 클래스 (패치 클래스)를 만들어 사용하는 것입니다.
일부는 만들어 놓았습니다.






다음 글들:



이어서 글올리기(답하기)

이름:
E-Mail:
제목:
내용:
관련 URL(선택):
URL 제목(선택):
관련 이미지 URL:


[ 다음 글들 ] [ 이어서 글올리기(답하기) ] [ 자바 묻고 답하기 ]