getWriter()



你可以從 HttpServletResponsegetWriter() 取得 PrintWriter 物件,透過該物件對客戶端進行字元輸出。在沒有設定任何內容型態或編碼之前,容器使用的字元編碼是 ISO-8859-1。

你可以使用 HttpServletResponsesetLocale() 來設定地區(Locale)資訊,setLocale() 必須在回應確認前設定,回應確認後設定地區資訊並沒有效果。容器如何與客戶端溝通並沒有規範,通常使用 Content-Language 標頭來設定。例如以下會將 HTTP 回應的 Content-Language 設定為 zh-TW:

response.setLocale(Locale.TAIWAN);

你可以使用 HttpServletResponsegetCharacterEncoding() 方法取得編碼設定,預設是 ISO-8859-1,可以在 web.xml 中設定區域與編碼的對應。例如:

<locale-encoding-mapping-list>
    <locale-encoding-mapping>
        <locale>zh_TW</locale>
        <encoding>UTF-8</encoding>
    </locale-encoding-mapping>
</locale-encoding-mapping-list>

若搭配先前的程式片段,或者是以下的程式片段,getCharacterEncoding() 取得的就是 UTF-8:

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

你也可以呼叫 HttpServletResponsesetCharacgerEncoding() 設定字元編碼:

response.setCharacterEncoding("UTF-8");

或者是在使用 HttpServletResponsesetContentType() 時,指定 charsetcharset 的值會用來呼叫 setCharacterEncoding()。例如:

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

如果使用了 setCharacterEncoding()setContentType() 時指定了 charset,則 setLocale() 就會被忽略。

在 Servlet 4.0 中,也可以在 web.xml 中加入 <response-character-encoding>,設定整個應用程式要使用的回應編碼,如此一來,就不用特別在每次請求使用 HttpServletResponsesetCharacterEncoding() 方法來設定編碼了 例如:

<response-character-encoding>UTF-8</response-character-encoding>

結合〈請求參數、標頭〉與這邊的說明,可以得知的是,如果你要可以接收中文請求參數並在回應時於瀏覽器顯示出來,必須設定 HttpServletRequestsetCharacterEncoding() 以及 HttpServletResponsesetCharacterEncoding()setContentType() 為正確的編碼,或者是在 web.xml 中設定 <request-character-encoding><response-character-encoding>

例如以下這個範例,可以讓你透過表單發送中文請求參數值,Servlet 可正確地接收處理並顯示在結果畫面上。你可以使用表單發送名稱、郵件與多選喜愛的寵物類型代表。首先是表單的部份:

<!DOCTYPE html>
<html>
    <head>
        <meta charset= "UTF-8">
        <title>寵物類型大調查</title>
    </head>
    <body>
        <form action="pet" method="post">
            姓名:<input type="text" name="user"><br>
            郵件:<input type="email" name="email"><br>
            你喜愛的寵物代表:<br>
            <select name="type" size="6" multiple>
                <option value="貓">貓</option>
                <option value="狗">狗</option>
                <option value="魚">魚</option>
                <option value="鳥">鳥</option>
            </select><br>
            <input type="submit" value="送出"/>
        </form>
    </body>
</html> 

接著是 Servlet 的部份:

package cc.openhome;

import java.io.*;
import java.util.Arrays;

import javax.servlet.*;
import javax.servlet.annotation.*;
import javax.servlet.http.*;

@WebServlet("/pet")
public class Pet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=UTF-8");

        PrintWriter out = response.getWriter();
        out.println("<!DOCTYPE html>");
        out.println("<html>");
        out.println("<body>");

        out.printf("聯絡人:<a href='mailto:%s'>%s</a>%n", 
            request.getParameter("email"), 
            request.getParameter("user")
        );

        out.println("<br>喜愛的寵物類型");
        out.println("<ul>");

        Arrays.asList(request.getParameterValues("type"))
              .forEach(type -> out.printf("<li>%s</li>%n", type));

        out.println("</ul>");
        out.println("</body>");
        out.println("</html>");
    }
}

在 Servlet 4.0 之前,若頁面很多,逐個頁面設定編碼是件很麻煩的事,所以設定編碼的動作其實不會直接在 Servlet 中進行,而會在過濾器(Filter)中設定,之後還會談到過濾器的細節。