TomcatでPOSTやGETリクエストのパラメータが文字化けするときの解決方法

Web開発を始める中でたまに遭遇することがある文字化け問題。HTMLにJavaコードを埋め込むことができるJSPでのWebアプリケーション開発でTomcatを利用している場合にもよくあります。
ここではTomcatでPOSTやGETリクエストのパラメータを扱う時に文字化けする問題についての解決方法をご紹介します。

 
例として、webappsの中に「sample」というプロジェクトフォルダを作成してその中にファイルを2つ用意して説明していきます。
ファイル名は適当に入力フォーム側は「sample.jsp」、受け取る側は「output.jsp」とします。

 
sample.jspで名前と生年月日を入力するフォームを用意します。

 
sample.jsp

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

<!DOCTYPE html>
<html>
<head>
  <title>Example JSP</title>
  <meta charset="UTF-8">
</head>
<body>

  <h1>入力フォームサンプル</h1>
  <div>
    <form method="post" action="output.jsp">
      お名前: <input type="text" name="name" size=32><br>
      生年月日: <input type="text" name="birthday" size=20><br>
      <input type="submit" value="OK">
    </form>
  </div>

</body>
</html>

 
output.jspでフォームで入力した値を取得して表示させます。

output.jsp

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

<%

// パラメータを取得
String name = request.getParameter("name");
String birthday = request.getParameter("birthday");

%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ユーザーからの入力を出力</title>
</head>
<body>
  <h1>ユーザーからの入力を出力</h1>
  <p>お名前: <%= name %></p>
  <p>生年月日: <%= birthday %></p>
</body>
</html>

 

入力フォームから名前と生年月日を入力すると、output.jspで値を受け取ると日本語が文字化けします。

TomcatでのPOSTやGETリクエストのパラメータの文字化け

 
TomcatではデフォルトのPOSTやGETパラメータのエンコーディングがISO-8859-1になっています。
入力フォーム側がUTF-8なのはもちろん、受け取る側もUTF-8なので文字コードが違って文字化けしてしまいます。
そこでTomcatの設定を変更する必要があります。

 

文字コードを調整する設定

Tomcatの設定ファイルであるserver.xmlを編集します。
server.xmlの場所はTomcatフォルダの「conf」フォルダの中にあります。

私の場合はアプリケーションフォルダの中にTomcatというフォルダを作成してその中にTomcatのフォルダを置いています。
ディレクトリは「/Applications/Tomcat/apache-tomcat-9.0.10/conf/server.xml」となります。

編集する箇所は大体69行目あたりにあるかと思います。
Connectorタグに「useBodyEncodingForURI=”true”」を追加します。
Connectorタグはリクエスト処理を行うための設定ができるものです。

server.xml
 
Tomcatで文字コードを調整する設定

 
useBodyEncodingForURIをtrueとすることでコード上のsetCharacterEncodingメソッドが効くようになります。
リクエストで受け取るパラメータの文字コードをUTF-8としてあげます。
パラメータを取得する前に記述します。

output.jsp
 
JSPファイルでパラメータの文字コードを調整

 

これでPOSTやGETで取得した値が文字化けすることなく表示させることができます。