你可以從 HttpServletResponse
的 getWriter()
取得 PrintWriter
物件,透過該物件對客戶端進行字元輸出。在沒有設定任何內容型態或編碼之前,容器使用的字元編碼是 ISO-8859-1。
你可以使用 HttpServletResponse
的 setLocale()
來設定地區(Locale)資訊,setLocale()
必須在回應確認前設定,回應確認後設定地區資訊並沒有效果。容器如何與客戶端溝通並沒有規範,通常使用 Content-Language
標頭來設定。例如以下會將 HTTP 回應的 Content-Language
設定為 zh-TW:
response.setLocale(Locale.TAIWAN);
你可以使用 HttpServletResponse
的 getCharacterEncoding()
方法取得編碼設定,預設是 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"));
你也可以呼叫 HttpServletResponse
的 setCharacgerEncoding()
設定字元編碼:
response.setCharacterEncoding("UTF-8");
或者是在使用 HttpServletResponse
的 setContentType()
時,指定 charset
,charset
的值會用來呼叫 setCharacterEncoding()
。例如:
response.setContentType("text/html; charset=UTF-8");
如果使用了 setCharacterEncoding()
或 setContentType()
時指定了 charset
,則 setLocale()
就會被忽略。
在 Servlet 4.0 中,也可以在 web.xml 中加入 <response-character-encoding>
,設定整個應用程式要使用的回應編碼,如此一來,就不用特別在每次請求使用 HttpServletResponse
的 setCharacterEncoding()
方法來設定編碼了 例如:
<response-character-encoding>UTF-8</response-character-encoding>
結合〈請求參數、標頭〉與這邊的說明,可以得知的是,如果你要可以接收中文請求參數並在回應時於瀏覽器顯示出來,必須設定 HttpServletRequest
的 setCharacterEncoding()
以及 HttpServletResponse
的 setCharacterEncoding()
或 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)中設定,之後還會談到過濾器的細節。