<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>OddPoet&#039;s βetalog &#187; Java</title>
	<atom:link href="http://oddpoet.net/archives/tag/java/feed" rel="self" type="application/rss+xml" />
	<link>http://oddpoet.net</link>
	<description>디지털과 아나로그의 경계에 서서...</description>
	<lastBuildDate>Mon, 12 Jul 2010 20:34:27 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>XStream에서 null값을 xml/json으로 serialize하기</title>
		<link>http://oddpoet.net/archives/192</link>
		<comments>http://oddpoet.net/archives/192#comments</comments>
		<pubDate>Wed, 14 Apr 2010 07:09:01 +0000</pubDate>
		<dc:creator>OddPoet</dc:creator>
				<category><![CDATA[개발]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[null]]></category>
		<category><![CDATA[xml serialize]]></category>
		<category><![CDATA[XStream]]></category>

		<guid isPermaLink="false">http://oddpoet.net/?p=192</guid>
		<description><![CDATA[XStream은 Java Object에 대한 xml serialize를 제공하는 Libraray입니다. 물론 deserialize도 지원하며, json 변환 역시 지원하지요. 
문제상황
하지만 XStream은 Object의 property 값이 null 인 경우에는 해당 property를 serialize 하지 않습니다. 예를 들면&#8230;


?View Code JAVA@XStreamAlias&#40;&#34;Person&#34;&#41;
class Person &#123;
	public String firstName;
	public String lastName;
	public String middleName;
&#125;
......
Person jobs = new Person&#40;&#41;;
jobs.firstName = &#34;Steve&#34;;
jobs.lastName = &#34;Jobs&#34;;
&#160;
XStream xstream = new XStream&#40;&#41;;
xstream.processAnnotations&#40;Person.class&#41;;
String xml = xstream.toXML&#40;jobs&#41;;
System.out.println&#40;xml&#41;;

위와 [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://xstream.codehaus.org/" onclick="pageTracker._trackPageview('/outgoing/xstream.codehaus.org/?referer=');">XStream</a>은 Java Object에 대한 xml serialize를 제공하는 Libraray입니다. 물론 deserialize도 지원하며, json 변환 역시 지원하지요. </p>
<h3>문제상황</h3>
<p>하지만 XStream은 Object의 property 값이 null 인 경우에는 해당 property를 serialize 하지 않습니다. 예를 들면&#8230;<br />
<span id="more-192"></span></p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?" onclick="pageTracker._trackPageview('/outgoing/www.ericbess.com/ericblog/2008/03/03/wp-codebox/_examples?referer=');"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p192code12'); return false;">View Code</a> JAVA</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p19212"><td class="code" id="p192code12"><pre class="java" style="font-family:monospace;">@XStreamAlias<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Person&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">class</span> Person <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">public</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Astring+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">String</span></a> firstName<span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">public</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Astring+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">String</span></a> lastName<span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">public</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Astring+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">String</span></a> middleName<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
......
<span style="color: #006633;">Person</span> jobs <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Person<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
jobs.<span style="color: #006633;">firstName</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;Steve&quot;</span><span style="color: #339933;">;</span>
jobs.<span style="color: #006633;">lastName</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;Jobs&quot;</span><span style="color: #339933;">;</span>
&nbsp;
XStream xstream <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> XStream<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
xstream.<span style="color: #006633;">processAnnotations</span><span style="color: #009900;">&#40;</span>Person.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Astring+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">String</span></a> xml <span style="color: #339933;">=</span> xstream.<span style="color: #006633;">toXML</span><span style="color: #009900;">&#40;</span>jobs<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Asystem+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>xml<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>위와 같은 코드는 아래와 같은 XML을 출력하게 됩니다.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?" onclick="pageTracker._trackPageview('/outgoing/www.ericbess.com/ericblog/2008/03/03/wp-codebox/_examples?referer=');"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p192code13'); return false;">View Code</a> XML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p19213"><td class="code" id="p192code13"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Person<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;firstName<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Steve<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/firstName<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;lastName<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Jobs<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/lastName<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Person<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>즉, null 값을 가진 middleName은 아예 serialize 되지 않습니다. 아마도 XStream이 Object를 deserialize 할 때 null과 공백문자열 간의 모호함을 제거하기 위해서 null을 serialize 하는 것으로 생각됩니다. (근거는 없습니다.) JSON으로 serialize 할 때도 마찬가지 결과를 보여줍니다.</p>
<p>어찌 됐던, 위와 같은 코드에서 아래와 같은 결과를 얻고 싶은 경우 XStream의 기본 기능만으로 해결할 수 없습니다.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?" onclick="pageTracker._trackPageview('/outgoing/www.ericbess.com/ericblog/2008/03/03/wp-codebox/_examples?referer=');"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p192code14'); return false;">View Code</a> XML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p19214"><td class="code" id="p192code14"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Person<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;firstName<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Steve<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/firstName<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;lastName<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Jobs<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/lastName<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;middleName</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Person<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<h3>해결방법(XML) : Converter 구현 </h3>
<p>null value serialize를 위해서 여러가지 접근 방법이 있겠지만, Converter를 구현해서 사용하는게 가장 심플합니다.<br />
아래코드는 null value를 빈 element로 변환하도록 하는 Converter 구현입니다.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?" onclick="pageTracker._trackPageview('/outgoing/www.ericbess.com/ericblog/2008/03/03/wp-codebox/_examples?referer=');"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p192code15'); return false;">View Code</a> JAVA</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p19215"><td class="code" id="p192code15"><pre class="java" style="font-family:monospace;"><span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * NullConverterHack.
 *
 * &lt;p&gt;
 * {@link XStream}으로 serialize 할때 기본적으로 null value를 skip처리하므로, 
 * 빈 엘리먼트를 삽입하도록 하는 {@link Converter} 클래스임. 
 * &lt;/p&gt;
 * &lt;p&gt;
 * 아래와 같은 형태로 사용한다. 반드시 LOW PRIORITY로 사용해야 함.
 * &lt;code&gt;
 *  xstream.registerConverter(new NullConverterHack(xstream.getMapper()), XStream.PRIORITY_LOW);
 * &lt;/code&gt;
 * &lt;/p&gt;
 * 
 * (주의) unmarshal을 지원하지 않는다.
 * 
 * @see JsonWriterHack Json으로 serialize 할 경우에는 {@link NullConverterHack}과 {@link JsonWriterHack}을 함께 사용한다.
 * @author oddpoet
 */</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> NullConverterHack <span style="color: #000000; font-weight: bold;">implements</span> Converter <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">private</span> Mapper mapper<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> NullConverterHack<span style="color: #009900;">&#40;</span>Mapper mapper<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">mapper</span> <span style="color: #339933;">=</span> mapper<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #008000; font-style: italic; font-weight: bold;">/**
	 * 모든 클래스에 대해서 작동.
	 * 
	 * @param type
	 * @return
	 * @see com.thoughtworks.xstream.converters.ConverterMatcher#canConvert(java.lang.Class)
	 */</span>
    @SuppressWarnings<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;unchecked&quot;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> canConvert<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">Class</span> type<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #008000; font-style: italic; font-weight: bold;">/**
     * marshalling.
     * 
     * @param source
     * @param writer
     * @param context
     * @see com.thoughtworks.xstream.converters.Converter#marshal(java.lang.Object, com.thoughtworks.xstream.io.HierarchicalStreamWriter, com.thoughtworks.xstream.converters.MarshallingContext)
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> marshal<span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aobject+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Aobject+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">Object</span></a> source, HierarchicalStreamWriter writer, MarshallingContext context<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    	<a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Afield+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Afield+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">Field</span></a> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> fieldSet <span style="color: #339933;">=</span> source.<span style="color: #006633;">getClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getDeclaredFields</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Afield+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Afield+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">Field</span></a> field <span style="color: #339933;">:</span> fieldSet<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    		<a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aobject+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Aobject+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">Object</span></a> member<span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>mapper.<span style="color: #006633;">shouldSerializeMember</span><span style="color: #009900;">&#40;</span>source.<span style="color: #006633;">getClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, field.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    			<span style="color: #000000; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
&nbsp;
    		field.<span style="color: #006633;">setAccessible</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
				member <span style="color: #339933;">=</span> field.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>source<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				<a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Astring+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">String</span></a> name <span style="color: #339933;">=</span> mapper.<span style="color: #006633;">serializedMember</span><span style="color: #009900;">&#40;</span>field.<span style="color: #006633;">getDeclaringClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, field.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
				<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>member <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	    			writer.<span style="color: #006633;">startNode</span><span style="color: #009900;">&#40;</span>name<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	    			<span style="color: #666666; font-style: italic;">// 값이 null이면 내용은 채우지 않고 startNode(), endNode()만 호출</span>
	    			writer.<span style="color: #006633;">endNode</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	    		<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
	    			ExtendedHierarchicalStreamWriterHelper.<span style="color: #006633;">startNode</span><span style="color: #009900;">&#40;</span>writer, name, member.<span style="color: #006633;">getClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	    			context.<span style="color: #006633;">convertAnother</span><span style="color: #009900;">&#40;</span>member<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	    			writer.<span style="color: #006633;">endNode</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	    		<span style="color: #009900;">&#125;</span>
			<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aillegalargumentexception+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Aillegalargumentexception+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">IllegalArgumentException</span></a> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aillegalaccessexception+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Aillegalaccessexception+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">IllegalAccessException</span></a> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
&nbsp;
    	<span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #008000; font-style: italic; font-weight: bold;">/**
     * unmarshal을 지원하지 않는다.
     * 
     * @param reader
     * @param context
     * @return
     * @see com.thoughtworks.xstream.converters.Converter#unmarshal(com.thoughtworks.xstream.io.HierarchicalStreamReader, com.thoughtworks.xstream.converters.UnmarshallingContext)
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aobject+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Aobject+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">Object</span></a> unmarshal<span style="color: #009900;">&#40;</span>HierarchicalStreamReader reader, UnmarshallingContext context<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Converter 구현 코드가 길지 않으니 자세한 설명은 생략하겠습니다. 실제 사용방법은 아래와 같습니다.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?" onclick="pageTracker._trackPageview('/outgoing/www.ericbess.com/ericblog/2008/03/03/wp-codebox/_examples?referer=');"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p192code16'); return false;">View Code</a> JAVA</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p19216"><td class="code" id="p192code16"><pre class="java" style="font-family:monospace;">Person jobs <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Person<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
jobs.<span style="color: #006633;">firstName</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;Steve&quot;</span><span style="color: #339933;">;</span>
jobs.<span style="color: #006633;">lastName</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">;</span>
jobs.<span style="color: #006633;">middleName</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
XStream xstream <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> XStream<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// Converter를 등록한다. 단, PRIORITY_LOW로 등록하도록 한다. </span>
xstream.<span style="color: #006633;">registerConverter</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> NullConverterHack<span style="color: #009900;">&#40;</span>xstream.<span style="color: #006633;">getMapper</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>, XStream.<span style="color: #006633;">PRIORITY_LOW</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
xstream.<span style="color: #006633;">processAnnotations</span><span style="color: #009900;">&#40;</span>Person.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Astring+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">String</span></a> xml <span style="color: #339933;">=</span> xstream.<span style="color: #006633;">toXML</span><span style="color: #009900;">&#40;</span>jobs<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Asystem+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>xml<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>위와 같은 방법으로 객체를 XML로 serialize 하면 아래와 같은 결과를 얻을 수 있습니다. 공백문자와 null이 다른 형식으로 표현되고 있음에 유의하세요.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?" onclick="pageTracker._trackPageview('/outgoing/www.ericbess.com/ericblog/2008/03/03/wp-codebox/_examples?referer=');"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p192code17'); return false;">View Code</a> XML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p19217"><td class="code" id="p192code17"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Person<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;firstName<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Steve<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/firstName<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;lastName<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/lastName<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> <span style="color: #808080; font-style: italic;">&lt;!-- 공백문자는 이렇게 --&gt;</span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;middleName</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span> <span style="color: #808080; font-style: italic;">&lt;!-- null은 이렇게 ... --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Person<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<h3> JSON의 경우 </h3>
<p>위와 같이 Converter를 추가해서 사용할 경우 XML 변환시 null 값에 대한 빈 element 출력은 가능합니다만, JSON 출력의 경우 아래와 같이 null 이 아닌 빈 객체({})로 출력되는 문제가 있습니다.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?" onclick="pageTracker._trackPageview('/outgoing/www.ericbess.com/ericblog/2008/03/03/wp-codebox/_examples?referer=');"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p192code18'); return false;">View Code</a> JAVA</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p19218"><td class="code" id="p192code18"><pre class="java" style="font-family:monospace;">Person jobs <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Person<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
jobs.<span style="color: #006633;">firstName</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;Steve&quot;</span><span style="color: #339933;">;</span>
jobs.<span style="color: #006633;">lastName</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">;</span>
jobs.<span style="color: #006633;">middleName</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
XStream xstream <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> XStream<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> JsonHierarchicalStreamDriver<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	@Override
	<span style="color: #000000; font-weight: bold;">public</span> HierarchicalStreamWriter createWriter<span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Awriter+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Awriter+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">Writer</span></a> out<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> JsonWriter<span style="color: #009900;">&#40;</span>out, JsonWriter.<span style="color: #006633;">DROP_ROOT_MODE</span> <span style="color: #339933;">|</span> JsonWriter.<span style="color: #006633;">STRICT_MODE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
xstream.<span style="color: #006633;">registerConverter</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> NullConverterHack<span style="color: #009900;">&#40;</span>xstream.<span style="color: #006633;">getMapper</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>, XStream.<span style="color: #006633;">PRIORITY_LOW</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
xstream.<span style="color: #006633;">processAnnotations</span><span style="color: #009900;">&#40;</span>Person.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Astring+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">String</span></a> xml <span style="color: #339933;">=</span> xstream.<span style="color: #006633;">toXML</span><span style="color: #009900;">&#40;</span>jobs<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Asystem+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>xml<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>즉 위와 같은 코드는 아래와 같은 JSON을 출력하게됩니다. null 대신 {}이 출력되지요.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?" onclick="pageTracker._trackPageview('/outgoing/www.ericbess.com/ericblog/2008/03/03/wp-codebox/_examples?referer=');"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p192code19'); return false;">View Code</a> JAVASCRIPT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p19219"><td class="code" id="p192code19"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
  <span style="color: #3366CC;">&quot;firstName&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Steve&quot;</span><span style="color: #339933;">,</span>
  <span style="color: #3366CC;">&quot;lastName&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">,</span>
  <span style="color: #3366CC;">&quot;middleName&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Conveter의 Interface를 보면 알 수 있겠지만, JSON 출력시의 null 문제를 풀기 위해서는 Conveter 레벨에서 처리가 안됩니다. 결국 Writer 레벨에서 null 처리를 해야합니다. 그런데 기존 JsonWriter를 상속받아서 해결할 수 없기 때문에, 깔끔하지는 않지만 기존 JsonWriter 소스를 복사해서 새로운 클래스를 만들고 관련된 부분을 수정합니다. 수정해야할 부분은 <strong>endNode()</strong> 함수입니다. (아래 소스 참고)</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?" onclick="pageTracker._trackPageview('/outgoing/www.ericbess.com/ericblog/2008/03/03/wp-codebox/_examples?referer=');"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p192code20'); return false;">View Code</a> JAVA</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p19220"><td class="code" id="p192code20"><pre class="java" style="font-family:monospace;"><span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * JsonWriterHack.
 *
 * &lt;p&gt;
 * XStream 패키지에 있는 {@link JsonWriter}에 수정을 가한 클래스이며, (상속받아서 해결 불가능함)
 * {@link NullConverterHack}과 함께 사용할 경우, null 값을 Json의 null로 변환해준다. 당연히 공백문자열(&quot;&quot;)과는 구분된다. 
 * &lt;/p&gt;
 * &lt;p&gt;
 * 수정된 부분은 {@link #endNode()} 함수이며, 수정한 부분에 comment를 달아놓았다.
 * 하지만 변경된 JsonWriter에 의해 사용시 예기치 못한 JSON 변환이 이루어질 수 있으므로, 주의하도록한다. 
 * &lt;/p&gt;
 * 
 * @see NullConverterHack {@link NullConverterHack}과 함께 사용해야 한다. 
 * @author oddpoet
 */</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> JsonWriterHack <span style="color: #000000; font-weight: bold;">implements</span> ExtendedHierarchicalStreamWriter <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// ... 나머지 코드는 JsonWriter와 동일하게 그대로 두고, endNode() 함수만 수정한다.</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> endNode<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		depth<span style="color: #339933;">--;</span>
		Node node <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>Node<span style="color: #009900;">&#41;</span>elementStack.<span style="color: #006633;">pop</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>node.<span style="color: #006633;">clazz</span> <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #339933;">&amp;&amp;</span> node.<span style="color: #006633;">isCollection</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>node.<span style="color: #006633;">fieldAlready</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				readyForNewLine <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
&nbsp;
			finishTag<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			writer.<span style="color: #006633;">write</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;]&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>tagIsEmpty<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			readyForNewLine <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
			writer.<span style="color: #006633;">write</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;null&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #666666; font-style: italic;">// &lt;- 이부분을 수정. 원래는 writer.write(&quot;{}&quot;); 였음.</span>
			finishTag<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
			finishTag<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>node.<span style="color: #006633;">fieldAlready</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				writer.<span style="color: #006633;">write</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;}&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		readyForNewLine <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>depth <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>mode <span style="color: #339933;">&amp;</span> DROP_ROOT_MODE<span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span> <span style="color: #339933;">||</span> <span style="color: #009900;">&#40;</span>depth <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">0</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>node.<span style="color: #006633;">isCollection</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			writer.<span style="color: #006633;">write</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;}&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			writer.<span style="color: #006633;">flush</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #666666; font-style: italic;">// 나머지 코드는 그대로 유지...</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>자 그럼, JsonWriter 대신 위에서 만든 JsonWriterHack으로 대체하면 원하는 null 출력을 볼 수 있습니다.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?" onclick="pageTracker._trackPageview('/outgoing/www.ericbess.com/ericblog/2008/03/03/wp-codebox/_examples?referer=');"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p192code21'); return false;">View Code</a> JAVA</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p19221"><td class="code" id="p192code21"><pre class="java" style="font-family:monospace;">Person jobs <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Person<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
jobs.<span style="color: #006633;">firstName</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;Steve&quot;</span><span style="color: #339933;">;</span>
jobs.<span style="color: #006633;">lastName</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">;</span>
jobs.<span style="color: #006633;">middleName</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
XStream xstream <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> XStream<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> JsonHierarchicalStreamDriver<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	@Override
	<span style="color: #000000; font-weight: bold;">public</span> HierarchicalStreamWriter createWriter<span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Awriter+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Awriter+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">Writer</span></a> out<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> JsonWriterHack<span style="color: #009900;">&#40;</span>out, JsonWriterHack.<span style="color: #006633;">DROP_ROOT_MODE</span> <span style="color: #339933;">|</span> JsonWriterHack.<span style="color: #006633;">STRICT_MODE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
xstream.<span style="color: #006633;">registerConverter</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> NullConverterHack<span style="color: #009900;">&#40;</span>xstream.<span style="color: #006633;">getMapper</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>, XStream.<span style="color: #006633;">PRIORITY_LOW</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
xstream.<span style="color: #006633;">processAnnotations</span><span style="color: #009900;">&#40;</span>Person.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Astring+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">String</span></a> xml <span style="color: #339933;">=</span> xstream.<span style="color: #006633;">toXML</span><span style="color: #009900;">&#40;</span>jobs<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Asystem+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>xml<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?" onclick="pageTracker._trackPageview('/outgoing/www.ericbess.com/ericblog/2008/03/03/wp-codebox/_examples?referer=');"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p192code22'); return false;">View Code</a> JAVASCRIPT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p19222"><td class="code" id="p192code22"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
  <span style="color: #3366CC;">&quot;firstName&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Steve&quot;</span><span style="color: #339933;">,</span>
  <span style="color: #3366CC;">&quot;lastName&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">,</span>
  <span style="color: #3366CC;">&quot;middleName&quot;</span><span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">null</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Json에서의 null serialize 의 경우, 기존 구현체를 Rewrite해야해서 그다지 깔끔한 방법은 아닙니다. XStream으로 JSON 출력제어를 하는데 제약이 있으므로, 다른 object &#8211; JSON 매핑 library를 사용하는게 좋을 수도 있습니다. </p>
]]></content:encoded>
			<wfw:commentRss>http://oddpoet.net/archives/192/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tomcat에서 한글파라메터 인코딩 처리</title>
		<link>http://oddpoet.net/archives/62</link>
		<comments>http://oddpoet.net/archives/62#comments</comments>
		<pubDate>Thu, 04 Feb 2010 08:07:31 +0000</pubDate>
		<dc:creator>OddPoet</dc:creator>
				<category><![CDATA[개발]]></category>
		<category><![CDATA[웹]]></category>
		<category><![CDATA[EUC-KR]]></category>
		<category><![CDATA[ISO-8859-1]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[MS949]]></category>
		<category><![CDATA[Tomcat]]></category>
		<category><![CDATA[UTF8]]></category>
		<category><![CDATA[한글 인코딩]]></category>

		<guid isPermaLink="false">http://oddpoet.net/?p=62</guid>
		<description><![CDATA[요즘 대부분 웹페이지의 한글페이지는 UTF-8로 개발되는 추세지만, EUC-KR로 개발된 사이트를 UTF-8로 전환하려고 하는 경우 외부에서의 링크 등 때문에 Request의 파라메터에 대해서 UTF-8과 EUC-KR을 모두 지원해야할 경우가 종종 있습니다. 하지만 Java는 PHP 등과는 달리 String을 byte array로 보는게 아니라, byte array를 decoding해서 유니코드로 처리하므로 Tomcat의 character encoding 설정 만으로는 파라메터에 대해서 UTF-8과 EUC-KR을 모두 지원할 수 [...]]]></description>
			<content:encoded><![CDATA[<p>요즘 대부분 웹페이지의 한글페이지는 UTF-8로 개발되는 추세지만, EUC-KR로 개발된 사이트를 UTF-8로 전환하려고 하는 경우 외부에서의 링크 등 때문에 Request의 파라메터에 대해서 UTF-8과 EUC-KR을 모두 지원해야할 경우가 종종 있습니다. 하지만 Java는 PHP 등과는 달리 String을 byte array로 보는게 아니라, byte array를 decoding해서 유니코드로 처리하므로 Tomcat의 character encoding 설정 만으로는 파라메터에 대해서 UTF-8과 EUC-KR을 모두 지원할 수 없습니다. 이런 상황에서 써볼 수 있는 팁을 정리해봅니다. <span id="more-62"></span></p>
<h3>가정</h3>
<ol>
<li>한글 인코딩은  UTF-8, EUC-KR(MS949) 만 고려합니다.</li>
<li>EUC-KR과 MS949가 동일한 character set은 아니지만, MS949가 EUC-KR의 확장이므로 이 글에서는 동일하게 취급합니다.</li>
<li>UTF8에 대해서는 국내에서 일반적인 다국어 환경(한글/영어 등)만 가정합니다.</li>
</ol>
<h3>Byte array 얻어내기</h3>
<p>UTF-8 으로 encoding된 byte array를 EUC-KR로 decoding해서 String 객체를 생성해버리면(반대의 경우도 마찬가지), 최상위 비트가 이미 손실된 상황이므로 String 객체 만으로는 한글 인코딩을 바꿔 다시 디코딩할 방법이 없습니다. 따라서 request parameter의 한글인코딩을 판단하고, 그에 맞는 적절한 인코딩 방법으로 parameter에 대한 String 객체를 생성하기 위해서는 우선적으로 parameter에 대한 String 객체가 아닌 byte array를 얻어낼 수 있어야 합니다.</p>
<p>그런데 문제는 HttpServletRequest에 request에 대한 byte array를 얻어낼 인터페이스가 없다는 점이죠. GET method의 Request의 경우 URL 정보에서 직접 파라메터를 파싱해내는 방법도 적용해볼 수 있지만, POST method의 요청에서는 그것도 불가능합니다. 게다가 GET인 경우에도 IE계열의 경우에는 uri encoding도 하지 않은 채로 보내주는 막강센스를 보여주기 때문에 로직이 좀 짜증이 납니다.</p>
<p>그래서 byte array를 얻어내기 위해서 저는 request에 characterEncoding을 &#8220;ISO-8859-1&#8243; 를 사용합니다. 그렇게 하면, String에서 원래 byte array를 얻어낼 수 있습니다.</p>

<div class="wp_codebox_msgheader wp_codebox_hide"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?" onclick="pageTracker._trackPageview('/outgoing/www.ericbess.com/ericblog/2008/03/03/wp-codebox/_examples?referer=');"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p62code28'); return false;">View Code</a> JAVA</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p6228"><td class="code" id="p62code28"><pre class="java" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">byte</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> barray<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// EUC-KR encoded byte array</span>
...
<a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Astring+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">String</span></a> ko2 <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Astring+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">String</span></a><span style="color: #009900;">&#40;</span>barray, <span style="color: #0000ff;">&quot;ISO-8859-1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">byte</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> barray2 <span style="color: #339933;">=</span> ko.<span style="color: #006633;">getBytes</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;ISO-8859-1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// barray2 is same as barray.</span>
&nbsp;
<a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Astring+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">String</span></a> ko2 <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Astring+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">String</span></a><span style="color: #009900;">&#40;</span>barray, <span style="color: #0000ff;">&quot;UTF-8&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">byte</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> barray3 <span style="color: #339933;">=</span> ko2.<span style="color: #006633;">getBytes</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;UTF-8&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// barray3 may be not same as barray.</span></pre></td></tr></table></div>

<p>tomcat의 경우 HttpServletRequest 객체에 처음으로 getParameter() 메소드를 호출할 때, paramter들의 파싱이 이루어지므로 첫번째 Filter에서 아래와 같은 코드로 전체 파라메터를 ISO-8859-1 로 decoding해서 String 객체를 생성하도록  할 수 있습니다.</p>

<div class="wp_codebox_msgheader wp_codebox_hide"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?" onclick="pageTracker._trackPageview('/outgoing/www.ericbess.com/ericblog/2008/03/03/wp-codebox/_examples?referer=');"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p62code29'); return false;">View Code</a> JAVA</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p6229"><td class="code" id="p62code29"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>isMultiPart<span style="color: #009900;">&#40;</span>request<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	request.<span style="color: #006633;">setCharacterEncoding</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;ISO-8859-1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// byte array으로 변환하기 위해 ISO-8859-1로 설정함.</span>
	request.<span style="color: #006633;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;dummy&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// parameter parsing을 위해서 getParameter 호출</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>자~ 그럼 파라메터에서 byte array를 다음과 같은 형태로 얻어낼 수 있겠죠?</p>

<div class="wp_codebox_msgheader wp_codebox_hide"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?" onclick="pageTracker._trackPageview('/outgoing/www.ericbess.com/ericblog/2008/03/03/wp-codebox/_examples?referer=');"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p62code30'); return false;">View Code</a> JAVA</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p6230"><td class="code" id="p62code30"><pre class="java" style="font-family:monospace;"><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Astring+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">String</span></a> query <span style="color: #339933;">=</span> request.<span style="color: #006633;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;query&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">byte</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> bQuery <span style="color: #339933;">=</span> query.<span style="color: #006633;">getBytes</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;ISO-8859-1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// 원래의 byte array를 얻음.</span></pre></td></tr></table></div>

<h3>UTF-8 인지 EUC-KR인지 판별하기</h3>
<p>byte array를 가져 왔으니 byte sequence로 부터 한글 인코딩을 판별해내야겠지요.</p>
<p>php 등의 스크립트 언어에서는 iconv 같은 함수들을 썼겠지만, 아시다시피 그런 방식으로는 한글 인코딩을 완전하게 판별할 수 없습니다. 왜냐하면 UTF-8 한글과 EUC-KR(MS949)와는 코드영역이 겹치는 부분이 있기 때문입니다. 예를 들면, &#8220;<em>천호</em>&#8220;, &#8220;<em>치킨</em>&#8221; 같은 단어들이죠.</p>
<ul>
<li>UTF-8 코드영역 : <a href="http://ko.wikipedia.org/wiki/UTF-8" onclick="pageTracker._trackPageview('/outgoing/ko.wikipedia.org/wiki/UTF-8?referer=');">http://ko.wikipedia.org/wiki/UTF-8</a></li>
<li>UTF-8 byte sequence에 대한 정규식 : <a href="http://www.w3.org/International/questions/qa-forms-utf-8.en.php" onclick="pageTracker._trackPageview('/outgoing/www.w3.org/International/questions/qa-forms-utf-8.en.php?referer=');">http://www.w3.org/International/questions/qa-forms-utf-8.en.php</a></li>
<li>MS949 코드영역 : <a href="http://ko.wikipedia.org/wiki/%EC%BD%94%EB%93%9C_%ED%8E%98%EC%9D%B4%EC%A7%80_949" onclick="pageTracker._trackPageview('/outgoing/ko.wikipedia.org/wiki/_EC_BD_94_EB_93_9C_ED_8E_98_EC_9D_B4_EC_A7_80_949?referer=');">http://ko.wikipedia.org/wiki/코드_페이지_949</a></li>
</ul>
<p>위의 링크를 참고하면, UTF-8의 <em>non-overlong 2-byte</em> 영역이 MS949의 코드 영역과 겹치는 걸 확인 할 수 있습니다. 즉, &#8220;<em>치킨</em>&#8220;이라는 단어의 경우 UTF8로 인코딩하면 <strong>EC.B9.98.ED.82.A8</strong> 인데 이 byte sequence는 UTF-8 인코딩에도 valid하며, MS949 인코딩에도 valid 합니다. 결론적으로 byte sequence 만으로는 UTF-8인지, EUC-KR인지 완벽하게 판별가능한 방법은 없다는 얘기입니다. (iconv 역시 마찬가지입니다.)</p>
<p>그래서 여기에 3번째 가정을 적용합니다. 위의 첫번째 링크(Wikipedia: UTF-8)의 내용 중에 아래와 같은 내용이 있습니다.</p>
<blockquote><p>그 다음 1920문자 &#8211; 발음 구별 기호가 붙은 라틴 문자, 그리스 문자, 키릴 문자, 콥트 문자, 아르메니아 문자, 히브리 문자, 아랍 문자 &#8211; 는 2바이트로 표시되며&#8230;</p></blockquote>
<p>UTF-8 코드영역에서 이 부분이 바로 <em>non-overlong 2-byte</em> 에 해당하는 부분입니다. 일반적으로 자주 쓰는 문자들은 아닌것 같죠? 이 코드 영역을 쓰지 않는다는 가정을 하면, 한글에 있어서는 완전하게 UTF-8과 EUC-KR 중 어떤 인코딩으로 encode된 byte array인지 판별가능합니다.</p>
<p>byte sequence에 대한 한글 UTF-8 여부를 판별하는 코드는 아래에 있습니다. 참고로 전체를 정규식으로 로직을 쓸 경우, 큰 byte array에 대해서 Stack overflow가 발생하기 때문에 아래와 같이 byte 별로 쪼개어 test했습니다.</p>

<div class="wp_codebox_msgheader wp_codebox_hide"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?" onclick="pageTracker._trackPageview('/outgoing/www.ericbess.com/ericblog/2008/03/03/wp-codebox/_examples?referer=');"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p62code31'); return false;">View Code</a> JAVA</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p6231"><td class="code" id="p62code31"><pre class="java" style="font-family:monospace;"><span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * 문자열이 UTF8 Character인지 검사하는 Utility Class.
 * &lt;p&gt;
 * byte arry 및 최상위 비트가 보존된 iso-8859-1로 decoding 문자열에 대한 체크만 가능하다. 
 * 한마디로, 이미 깨진 한글 따윈 검증할 수 없다. 
 * &lt;/p&gt;
 * &lt;p&gt;
 * utf8 문자셋에 대한 정규식. 
 * &lt;br/&gt;
 * MS949와 충돌나는 코드 영역 때문에, 2byte로 인코딩되는 문자들은 제외한다. (e.g. 치킨)
 * 한글 유니코드는 모두 /u0800 보다 큰 코드값에 배열되므로, 
 * utf8 인코딩시 2바이트로 인코딩되는 일이 없다. (첫자끝, 한글자모도 동일함)
 * 물론, 이렇게 함으로써 해당 코드영역을 사용하는 타언어의 코드를 체크할 수 없다. 
 * &lt;/p&gt;
 * 
 * 관련 정보 : 
 * 	1. http://ko.wikipedia.org/wiki/UTF-8
 *  2. http://forum.standardmag.org/viewtopic.php?id=462 
 * 
 * @see http://www.w3.org/International/questions/qa-forms-utf-8.en.php
 * 
 * @author oddpoet
 */</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000000; font-weight: bold;">class</span> UTF8KoreanChecker <span style="color: #009900;">&#123;</span>
	<span style="color: #008000; font-style: italic; font-weight: bold;">/**
	 * Utility Class이므로 생성자를 막는다. 
	 */</span>
	<span style="color: #000000; font-weight: bold;">private</span> UTF8KoreanChecker<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #008000; font-style: italic; font-weight: bold;">/**
	 * 주어진 byte array가 한글 UTF8 인코딩인지 체크한다. 
	 *  
	 * @param bytes bytes
	 * @return true/false
	 */</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">boolean</span> isUTF8Korean<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> bytes<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> bytes.<span style="color: #006633;">length</span><span style="color: #339933;">;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isAscii<span style="color: #009900;">&#40;</span>bytes, i<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				i <span style="color: #339933;">+=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// 1byte 체크함. </span>
				<span style="color: #000000; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #666666; font-style: italic;">/*
			 * 위에서 언급한 바처럼, UTF-8 인코딩의 2바이트 영역이 MS949와 겹치므로, 
			 * 한글 UTF8 검증에는 사용하지 않는다. 
			 * 게다가 한글 UTF8은 2바이트로 인코딩되는 경우가 없으므로, 
			 * 한글에 한해서는 체크는 완전하게 가능하다. 
			} else if (isNonOverlong(bytes, i)) {
				i += 2; 
				continue; 
			}
			 */</span>
&nbsp;
			<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isExcludeOverlogs<span style="color: #009900;">&#40;</span>bytes, i<span style="color: #009900;">&#41;</span> 
				<span style="color: #339933;">||</span> isExcludingSurrogates<span style="color: #009900;">&#40;</span>bytes, i<span style="color: #009900;">&#41;</span> 
				<span style="color: #339933;">||</span> isStraight<span style="color: #009900;">&#40;</span>bytes, i<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				i <span style="color: #339933;">+=</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// 3byte 체크함. </span>
				<span style="color: #000000; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isPlane1to3<span style="color: #009900;">&#40;</span>bytes, i<span style="color: #009900;">&#41;</span> 
				<span style="color: #339933;">||</span> isPlane4to15<span style="color: #009900;">&#40;</span>bytes, i<span style="color: #009900;">&#41;</span> 
				<span style="color: #339933;">||</span> isPlane16<span style="color: #009900;">&#40;</span>bytes, i<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				i <span style="color: #339933;">+=</span> <span style="color: #cc66cc;">4</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// 3byte 체크함. </span>
				<span style="color: #000000; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #008000; font-style: italic; font-weight: bold;">/**
	 * (1byte)ascii ([\\x09\\x0A\\x0D\\x20-\\x7E])
	 * @param bytes bytes
	 * @param index 체크시작할 바이트 
	 * @return true/false
	 */</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">boolean</span> isAscii<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> bytes, <span style="color: #000066; font-weight: bold;">int</span> index<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">return</span> bytes<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0x09 
			<span style="color: #339933;">||</span> bytes<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0x0A 
			<span style="color: #339933;">||</span> bytes<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0x0D 
			<span style="color: #339933;">||</span> <span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0x20 
				<span style="color: #339933;">&amp;&amp;</span> bytes<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0x7E
			<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #008000; font-style: italic; font-weight: bold;">/**
	 * (3bytes) excluding overlogs (\\xE0[\\xA0-\\xBF][\\x80-\\xBF])
	 * @param bytes bytes
	 * @param index index
	 * @return true/false
	 */</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">boolean</span> isExcludeOverlogs<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> bytes, <span style="color: #000066; font-weight: bold;">int</span> index<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">return</span> index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span> <span style="color: #339933;">&lt;</span> bytes.<span style="color: #006633;">length</span> 
			<span style="color: #339933;">&amp;&amp;</span> bytes<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xE0 
			<span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xA0 
				<span style="color: #339933;">&amp;&amp;</span> bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xBF
			<span style="color: #009900;">&#41;</span>
			<span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0x80 
				<span style="color: #339933;">&amp;&amp;</span> bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xBF
			<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #008000; font-style: italic; font-weight: bold;">/**
	 * (3bytes) straight ([\\xE1-\\xEC\\xEE\\xEF][\\x80-\\xBF]{2})
	 * @param bytes bytes
	 * @param index index
	 * @return true/false
	 */</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">boolean</span> isStraight<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> bytes, <span style="color: #000066; font-weight: bold;">int</span> index<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">return</span> index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span> <span style="color: #339933;">&lt;</span> bytes.<span style="color: #006633;">length</span> 
				<span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>
					<span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xE1 
						<span style="color: #339933;">&amp;&amp;</span> bytes<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xEC
					<span style="color: #009900;">&#41;</span> 
					<span style="color: #339933;">||</span> bytes<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xEE 
					<span style="color: #339933;">||</span> bytes<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xEF
				<span style="color: #009900;">&#41;</span>
				<span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0x80 
					<span style="color: #339933;">&amp;&amp;</span> bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xBF
				<span style="color: #009900;">&#41;</span> 
				<span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0x80 
					<span style="color: #339933;">&amp;&amp;</span> bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xBF
				<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #008000; font-style: italic; font-weight: bold;">/**
	 * (3bytes) excluding surrogates (\\xED[\\x80-\\x9F][\\x80-\\xBF])
	 * @param bytes bytes
	 * @param index index
	 * @return true/false
	 */</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">boolean</span> isExcludingSurrogates<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> bytes, <span style="color: #000066; font-weight: bold;">int</span> index<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">return</span> index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span> <span style="color: #339933;">&lt;</span> bytes.<span style="color: #006633;">length</span> 
			<span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xED<span style="color: #009900;">&#41;</span> 
			<span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0x80 
				<span style="color: #339933;">&amp;&amp;</span> bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0x9F
			<span style="color: #009900;">&#41;</span>
			<span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0x80 
				<span style="color: #339933;">&amp;&amp;</span> bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xBF
			<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #008000; font-style: italic; font-weight: bold;">/**
	 * (4bytes)planes 1-3 (\\xF0[\\x90-\\xBF][\\x80-\\xBF]{2})
	 * @param bytes bytes
	 * @param index index
	 * @return true/false
	 */</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">boolean</span> isPlane1to3<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> bytes, <span style="color: #000066; font-weight: bold;">int</span> index<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">return</span> index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">3</span> <span style="color: #339933;">&lt;</span> bytes.<span style="color: #006633;">length</span> 
			<span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xF0<span style="color: #009900;">&#41;</span> 
			<span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0x90 
				<span style="color: #339933;">&amp;&amp;</span> bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xBF
			<span style="color: #009900;">&#41;</span>
			<span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0x80 
				<span style="color: #339933;">&amp;&amp;</span> bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xBF
			<span style="color: #009900;">&#41;</span> 
			<span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">3</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0x80 
				<span style="color: #339933;">&amp;&amp;</span> bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">3</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xBF
			<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #008000; font-style: italic; font-weight: bold;">/**
	 * planes 4-15 ([\\xF1-\\xF3][\\x80-\\xBF]{3})
	 * @param bytes bytes
	 * @param index index
	 * @return true/false
	 */</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">boolean</span> isPlane4to15<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> bytes, <span style="color: #000066; font-weight: bold;">int</span> index<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">return</span> index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">3</span> <span style="color: #339933;">&lt;</span> bytes.<span style="color: #006633;">length</span> <span style="color: #666666; font-style: italic;">// 4byte check</span>
			<span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xF1 
				<span style="color: #339933;">&amp;&amp;</span> bytes<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xF3
			<span style="color: #009900;">&#41;</span> 
			<span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0x80 
				<span style="color: #339933;">&amp;&amp;</span> bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xBF
			<span style="color: #009900;">&#41;</span>
			<span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0x80 
				<span style="color: #339933;">&amp;&amp;</span> bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xBF
			<span style="color: #009900;">&#41;</span> 
			<span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">3</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0x80 
				<span style="color: #339933;">&amp;&amp;</span> bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">3</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xBF
			<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #008000; font-style: italic; font-weight: bold;">/**
	 * (4bytes)plane 16 (\\xF4[\\x80-\\x8F][\\x80-\\xBF]{2})
	 * @param bytes bytes
	 * @param index index
	 * @return true/false
	 */</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">boolean</span> isPlane16<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> bytes, <span style="color: #000066; font-weight: bold;">int</span> index<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">return</span> index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">3</span> <span style="color: #339933;">&lt;</span> bytes.<span style="color: #006633;">length</span> <span style="color: #666666; font-style: italic;">// 4byte check</span>
			<span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#91;</span>index<span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xF4<span style="color: #009900;">&#41;</span> 
			<span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0x80 
				<span style="color: #339933;">&amp;&amp;</span> bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0x8F
			<span style="color: #009900;">&#41;</span>
			<span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0x80 
				<span style="color: #339933;">&amp;&amp;</span> bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xBF
			<span style="color: #009900;">&#41;</span> 
			<span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">3</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0x80 
				<span style="color: #339933;">&amp;&amp;</span> bytes<span style="color: #009900;">&#91;</span>index <span style="color: #339933;">+</span> <span style="color: #cc66cc;">3</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&lt;=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span>0xBF
			<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #008000; font-style: italic; font-weight: bold;">/**
	 * (2bytes)non-overlong ([\\xC2-\\xDF][\\x80-\\xBF])
	 * 이 코드 영역은 MS949와 겹치는 영역이므로, 한글 검증용으로 사용하지 않는다. 
	 * 
	 * UTF8 한글의 경우 2byte로 인코딩되는 경우가 없음. 
	 * 
	 * @param bytes bytes
	 * @param index index
	 * @return true/false
	 */</span>
	<span style="color: #666666; font-style: italic;">/* 사용하지 않으므로 주석처리. 
	private static boolean isNonOverlong(byte[] bytes, int index) {
		return index + 1 &lt; bytes.length // 2byte check
			&amp;&amp; bytes[index] &gt;= (byte)0xC2 &amp;&amp; bytes[index] &lt;= (byte)0xDF
			&amp;&amp; bytes[index + 1] &gt;= (byte)0x80 &amp;&amp; bytes[index + 1] &lt;= (byte)0xBF;
	}
	*/</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h3>정리</h3>
<p>byte array를 얻어서, 사용된 encoding을 판별하고 나면 아래와 같은 방법으로 적절한 encoding을 사용해서 한글 String 객체를 만들어 낼 수 있습니다.</p>

<div class="wp_codebox_msgheader wp_codebox_hide"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?" onclick="pageTracker._trackPageview('/outgoing/www.ericbess.com/ericblog/2008/03/03/wp-codebox/_examples?referer=');"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p62code32'); return false;">View Code</a> JAVA</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p6232"><td class="code" id="p62code32"><pre class="java" style="font-family:monospace;"><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Astring+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">String</span></a> param <span style="color: #339933;">=</span> request.<span style="color: #006633;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;param&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">byte</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> bytes <span style="color: #339933;">=</span> param.<span style="color: #006633;">getBytes</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;ISO-8859-1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Astring+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">String</span></a> koparam<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>UTF8KoreanChecker.<span style="color: #006633;">isUTF8Korean</span><span style="color: #009900;">&#40;</span>bytes<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	koparam <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Astring+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">String</span></a><span style="color: #009900;">&#40;</span>bytes, <span style="color: #0000ff;">&quot;UTF-8&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
	koparam <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky" onclick="pageTracker._trackPageview('/outgoing/www.google.com/search?hl=en_amp_q=allinurl_3Astring+java.sun.com_amp_btnI=I_27m_20Feeling_20Lucky&amp;referer=');"><span style="color: #003399;">String</span></a><span style="color: #009900;">&#40;</span>bytes, <span style="color: #0000ff;">&quot;MS949&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://oddpoet.net/archives/62/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
