14.2. JSP / Servlet 怎樣才能處理中文?

鄭原真 Yuan-Chen Cheng Copyright 2000.

本文版權 : GPL or BSD style,請保留作者姓名。

本文假設您已經會使用 JSP 或是 Servlet 撰寫英文的 Web-Page。 如果您還不會,或是根本不知道 JSP 或是 Servlet 是幹什麼的, 那這篇文章不是寫給您看的。

在 Java Servlet Spec v2.0 中,對於多國語言的支援,並不足。 您必須找到 Java Servlet Spec v2.2 的實作才行,筆者試過的 是 Apache Jakarta Tomcat 3.1 軟體(註一)。

本文測試平台是 Debian Woody, Sun jdk1.2.2, Tomcat 3.1, mm.mysql-2.0.2

Java Server 如何處理中文。

前言

首先,如何正確的了解您一個 Big5 中文在 Java 中是正確的 中文 Unicode 呢?

輸出一個 String("今").length() 吧 ! 由於 "今" 在 Big5 是由兩個 byte 組成,但對 java 來說,java 的字元是 unicode,也就是說, 無論是一個英文字或是一個中文字,其 length() 都是 1. 也就是說, (new String("今")).length() ==> 1。才是正確的。

Servlet 輸出中文的一個例子。

下面是一個典型的 Java Servlet。

    HelloWorldExample.java =>
    ----------- cut here -----------------
    import java.io.*;
    import java.text.*;
    import java.util.*;
    import javax.servlet.*;
    import javax.servlet.http.*;
    
    public class HelloWorldExample extends HttpServlet {
    
        public void doGet(HttpServletRequest request,
                          HttpServletResponse response)
            throws IOException, ServletException
        {
            response.setLocale(new Locale(new String("zh"), new String("TW")));
            response.setContentType("text/html");
            PrintWriter out = response.getWriter();
    
            out.println("<html>");
            out.println("<head>");
    
            String title = new String("hello 大家好");
    
            out.println("<title>" + title + "</title>");
            out.println("</head>");
            out.println("<body bgcolor=\"white\">");
            out.println("<body>");
    
            out.println("<p>");
    
            out.println("<h1>" + title + "</h1>");
            out.println("</body>");
            out.println("</html>");
        }
    }
    ----------- cut here -----------------

可以正常輸出中文的關鍵是:

            response.setLocale(new Locale(new String("zh"), new String("TW")));

注意這一行應該要放在

            PrintWriter out = response.getWriter();

之前執行。另外編譯時注意

            javac -encoding Big5 HelloWorldExample.java

或是 (linux 上的 jdk1.2.2)

            export LANG=zh_TW.Big5
            export LC_CTYPE=zh_TW.Big5
            javac HelloWorldExample.java

注意,這個例子在 jserv v1.1.2 並不能 work,因為該版本實做的 JavaSoft Java Servlet APIs 2.0, 而 setLocale 是到 Servlet APIs 2.2 才有。

Java Server Page 如何處理中文

在此簡略說明,先看下面的例子:

    test.jsp
    ----------------------
    <%@ page contentType="text/html; charset=big5" %>
    <html>
    <body bgcolor="white">
        中文TEST.<p>
        <%= (new String("今天")).length() %>
        out.println("大家好");
    </body>
    </html>
    ----------------------

關鍵在第一行。有了這一行就行了。

而如果使用 POST 時,要使用中文就先看下面的例子

    test2.jsp
    ----------------------
    <html>
    <head>
        <title>Instropection</title>
    </head>
    <meta http-equiv="Content-Type" content="text/html; charset=big5">
    <body>
    <body bgcolor="#FFFFFF" text="#000000">
    <form name="form1" action="test3.jsp" method="post"  >
      <p> 姓名:
        <input type="text" name="name">
      </p>
      <p>編號:
        <input type="text" name="number">
      </p>
      <p>
        <input type="submit" value="傳送">
        <input type="reset" value="清除">
      </p>
    </form>
    </body>
    </html>
    ----------------------
    
    test3.jsp
    ----------------------
    <%@ page language="java" contentType="text/html;charset=Big5" %>
    <html>
    <head>
        <title>Instropection</title>
    </head>
    <body>
    <%
        String name = new String(request.getParameter("name").getBytes("ISO-8859-1"), "Big5");
        String number = request.getParameter("number");
    %>
    姓名:<%= name %>
    <br>編號:<%= number %>
    </body>
    </html>
    ----------------------

關鍵在於 String(str.getBytes("ISO-8859-1"), "Big5"), java.lang.String 的建構函式可以產生指定特定語系的 String, 透過這個範例,可以使 String 正確地轉換中文。

For Hacker:

理論上這一行可以放在文件的任何地方,但由於 Java 時做上 開檔案後通常就必須指定 encoding,當 java jsp engine 發現 charset 跟 default 不同時,通常必須重新開檔案。所以實做上 這一行放在越前面越好。不過話是這樣說,由於通常 jsp 會在 run time 被 compile 成 java bytecode,也就是說只有在 .jsp 更新時才需要 recompile。overhead 實在有限。

註一:請到 http://jakarta.apache.org/ 下去 Download。