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。