2009년 4월 30일 목요일

UTF-8을 기본 문자셋으로 사용하지 않는 시스템에서의 UTF-8 사용하기

최근 웹 표준을 기반으로 한 웹 사이트 기획이나 설계, 구현이 많이 이루어지고 있는 추세이다. 참 다행인 듯 하다.
웹 표준엔 XHTML + CSS + JavaScript를 이용한 프리젠테이션 영역의 이슈를 주로 다루고 있는데, 추가적으로 반드시 다루어야 하는 부분이 Character set 에 대한 표준이다.
Character set에 대한 표준은 단순히 웹 표준에서 뿐 만이 아니라 웹 애플리케이션, 응용 애플리케이션에 이르기까지 개발 전체적인 측면에서 표준으로 다루어야 한다.
그럼면에서 UTF-8을 기반으로 한 개발 표준을 다룰 줄 알아야 하고, 그에 따른 경험이 중요하다고 하겠습니다.

다행히 Java는 UTF-8을 기본으로 지원하기 때문에 구현이나 연동 상에 별다른 문제는 발생하지 않는다. 다만 타 시스템 간에 연동이나 UTF-8을 기본 문자셋으로 설정해 두지 않은(예를들면, Windows 같은) 시스템에서의 팁을 제공하고자 한다.

여기선 타 시스템 간의 연동에 대해서는 다루지 않고, 윈도우 같은 기본 문자셋을 UTF-8을 사용하지 않는 시스템에서의 웹 애플리케이션 구현히 발생할 수 있는 한 가지를 다루고자 한다.

자바는 문자셋을 시스템의 문자셋을 기본으로 VM이 가동되기 때문에 String을 처리할 때는 해당 문자셋 형태로 지원한다. 그래도 데이터베이스 + WAS + 웹 애플케이션을 UTF-8 형태로 맞추어두고 개발하게 된다. 이 때 발생할 수 있는 문제가 서버에서 XML을 리턴한다든지, response로 보내는 것이 HTML이 아닌 별도의 프로토콜에 의한 문자열을 반환할 때가 있다. 대표적인 것이 XML을 응답으로 주는 것이다.

이럴 때, 보통은 Servlet을 이용하여 HTTP Body에 XML을 실어서 보내게 되는데, String 처리까지는 UTF-8을 기반으로 한 코딩이 별도의 설정이나 기법없이 가능하다. 그리고 최종 아래와 같이 XML 문자열을 반환한다.

String xmlData = "뭐라뭐라";

PrintWriter out = response.getWriter();
        
out.println(xmlData);
        
out.flush();
out.close();


이 때, HTTP Response 객체를 이용한 HTTP Header를 셋팅해 주어야 하는데, 해당 문자열의 크기(즉, HTTP Body), Content Type 등을 다음과 같이 지정해 준다.

response.setContentLength(xmlData.getBytes().length);
response.setContentType("application/xml");
response.setCharacterEncoding("utf-8");


Content Length에 해당하는 결과 값으로 주어지는 String의 length가 실제 HTTP Body의 크기가 된다. 혹시나 실수로 xmlData.length() 함수를 사용하여 Content Length를 지정하는 일이 없길 바란다. 이러한 로직의 응답시에는 반드시 String의 lenght가 아니라 String byte의 length를 사용해야 한다.

그런데, 위의 예처럼 xmlData.getBytes().length 를 그대로 이용하여 UTF-8을 기본 문자셋으로 사용하지 않는 시스템에 서버 애플리케이션을 올려두면 한글이 들어간 XML인 경우에는 분명히 사이즈가 다르게 전달된다. 그래서 XML이 정상적으로 클라이언트에 전달되지 않는다.

이럴 때 아래와 같이 명시적으로 String의 byte 문자셋을 UTF-8으로 지정해 주어야 한다.

response.setContentLength(xmlData.getBytes("UTF-8").length);
response.setContentType("application/xml");
response.setCharacterEncoding("utf-8");


그러면, 소스 레벨에서 String의 문자셋을 UTF-8 형태로 byte를 얻어오기 때문에 정상적인 처리가 가능하다.

단순히 웹 사이트나 통일된 환경에서의 처리에는 이와 같은 팁이 유용하지 않치만 타 시스템 간의 연동이나 개발/운영된 환경에서 벗어난 포팅등에서는 유용하게 사용될 만한 팁이라 할 수 있다.

댓글 없음: