JavaのWebアプリで文字化けするのはなぜ?フォーム送信とUTF-8の関係|確認問題の回答例

このページは、JavaのWebアプリで文字化けするのはなぜ?フォーム送信とUTF-8の関係の確認問題の回答例です。
問題1:設定の順番を直す
request.setCharacterEncoding("UTF-8");
String userName = request.getParameter("userName");
response.setContentType("text/plain; charset=UTF-8");
PrintWriter out = response.getWriter();
out.println(userName);
requestの指定はgetParameterより前、responseの指定はgetWriterより前です。すでに読んだStringは、後からrequestの設定を変えても読み直されません。また、文字の出力前でも、Writerを取得した後ではそのWriterの文字コードを変更できません。
問題2:受信時に読み間違えた場合
固定の文字: 山田
受信した文字: 螻ア逕ー
正常なサンプルのrequest指定だけをShift_JISに変えると、UTF-8で届いたバイトを別のルールで読むため、受信した値が変わります。固定の「山田」はその受信処理を通りません。responseは最初からUTF-8なので、指定し直しても取得済みの値は直りません。requestの指定をUTF-8に戻してから、フォームをもう一度送信します。
問題3:JSPの2つの指定
| 指定 | 役割 |
|---|---|
pageEncoding | JSPソースファイルを読む文字コード |
contentType のcharset | JSPが返す応答の文字コード |
どちらも、POST本文をgetParameterで読むときの文字コード指定ではありません。ファイル・受信・応答は分けて考えます。POST本文は、その読み取りより前にrequest側で設定します。
問題4:GETだけで起きる場合
言い切れません。request.setCharacterEncodingが対象とするのは本文で、GETの検索条件はURLのクエリ文字列に入ります。送信されたURLやサーバーのURL読み取り設定を確認します。Tomcat 10.1ならURIEncodingが関係し、既定値はUTF-8です。POST本文とURLの読み取りを区別する必要があります。