JSP 的轉譯


這是一個簡單的JSP:

<%@ page contentType="text/html" pageEncoding="Big5"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="Big5">
<title>JSP 網頁</title>
</head>
<body>
    <%= new java.util.Date() %>
</body>
</html>

JSP 最後會轉譯為 Servlet,有關編碼方面的設定,最主要的是:

<%@ page contentType="text/html" pageEncoding="Big5"%>

在 Tomcat 中,容器會將 JSP 轉譯為 .java,.java 以 Big5 儲存,並以 Big5 編譯 .java, pageEncoding 主要是告知容器,這個 JSP 檔案的文字編碼為何,以正確地將字元轉譯至 .java, pageEncoding 也會影響內容類型(Content type),在沒有設定 contentType 屬性時,僅設定 pageEncoding 為Big5,產生的 .java 會有以下內容:

response.setContentType("text/html; charset=Big5");

如果 JSP 設定 contentType 時,沒有指定 charset,如上面那個簡單的 JSP 僅設定 text/html,那 pageEncoding 設定為 Big5 時,也會產生:

response.setContentType("text/html;charset=Big5");

如果故意這麼設定:

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="Big5"%>

那產生的 Servlet 中會包括:

response.setContentType("text/html;charset=UTF-8");

這些是在 Tomcat 上的情況,為了避免困擾,通常在設定 contentType 屬性時,charset 會設定為與 pageEncoding 一致:

<%@ page contentType="text/html; charset=Big5" pageEncoding="Big5"%>

responsesetContentType(),會在 HTTP 回應中產生 Content-Type 標頭,告知瀏覽器所使用的內容類型與編碼,瀏覽器會根據其中的編碼指示來解譯傳回的 HTML,HTML 中的提示:

<meta charset="Big5">

也是給瀏覽器參考用的,通常瀏覽器會以 Content-Type 標頭指示優先,meta 指示次之。

可以在 web.xml 中統一預設的網頁編碼、內容類型、緩衝區大小等,例如:

<web-app …>
    …
    <jsp-config>
        <jsp-property-group>
            <url-pattern>*.jsp</url-pattern>
            <page-encoding>UTF8</page-encoding>
            <default-content-type>text/html</default-content-type>
            <buffer>16kb</buffer>
        </jsp-property-group>
    </jsp-config>
</web-app>

如此一來,JSP 若沒有明確用 page 指示元素指定 contentTypepageEncoding 屬性,會使用 web.xml 中的設定。