2013年1月7日 星期一

Tomcat Charset Encoding

使用Tomcat如遇到編碼問題,在網路上查詢通常會有三種方法如下:
  1. 加上java系統變數-Dfile.encoding=UTF-8
  2. 在取得parameter時先呼叫request.setCharacterEncoding("UTF-8")
  3. 在Tomcat server.xml中的connector加上URIEncoding="UTF-8"
事實上這三者的影響範圍不同,差異如下:
  1. -Dfile.encoding主要是影響java.io.*,若沒有設定,java預設會以OS的編碼為主。
  2. Tomcat預設會以ISO8859-1抓取parameter,request.setCharacterEncoding("UTF-8")也只決定parameter的編碼為何。這部分我慣用org.springframework.web.filter.CharacterEncodingFilter解決,設定如下:
    代碼:
    <filter>
      <filter-name>characterEncoding</filter-name>
      <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
      <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
      </init-param>
      <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
      </init-param>
    </filter>
    代碼:
    <filter-mapping>
      <filter-name>characterEncoding</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
  3. URIEncoding="UTF-8"這個設定在Tomcat 5之後才開始重要,在Tomcat 4之前,query string的編碼和上項一致,但是在Tomcat 5之後被分開了,若是parameter被串成query string,則編碼還是為ISO8859-1,通常會在使用ajax時比較容易出錯,加上這個設定就會讓Tomcat一樣用指定編碼抓取query string所帶的parameter。
    範例:
    代碼:
    <Connector port="8080"
      maxHttpHeaderSize="8192" maxThreads="150"
      minSpareThreads="25" maxSpareThreads="75"
      enableLookups="false" redirectPort="8443"
      acceptCount="100" connectionTimeout="20000"
      disableUploadTimeout="true" URIEncoding="UTF-8" />