HTML(form) → Java(Servlet) で文字化けが起きてハマった話
HTML(form) → Java(Servlet) で文字化けが起きてハマりました
Webアプリを作っているときに、HTMLからJavaにデータを送ろうとして軽くハマりました。無事に解決できましたので、その方法をご紹介します。
およそ一日ハマっていたので業務上では軽くじゃ済まないんですが、人生から見たときには一日は比較的軽いものです。私は視野を広く持っています(上司はどう思うかわかりませんが)。
ではまず状況からいくと、HTMLのformで JavaのServletクラスを指定してPOSTでデータを送信しました。しかし、Javaに送られてきたのは見るも文字化けしたデータだったのです。
この解決法として、javascriptを経由すればjQueryのajaxで簡単に解決することは出来ます。しかし、いつもこの方法ばかり使っていては学習にならないのでこの構成での解決方法を模索しました。
実行環境
様々な方法が様々なブログで紹介されていたのですが、なかなか文字化けは治りませんでした。ブログ書いた人は本当に直ったの?これはおそらく環境が違うからだと思います。
私はWindows10にTomcat9サーバー立てて実施しています。おそらくブログで紹介されていた環境はLinux上にサーバー立てたりTomcatのバージョンが違ったりで実施している方が多いのでしょう。
ともあれ、私が試した方法は次のとおり。私は一日試行錯誤しましたが、みなさんはこの記事を読めば一瞬で解決することが出来ます。ラッキーですね!
私が試した方法
私が試した方法は次のとおり3つに大別することが出来ます。それぞれどんなことを考えて、具体的に何をしたのかを書いていきます。
1.HTML
2.Servlet
3.Filter
1.HTML
・head要素にmeta要素追加
<meta charset="UTF-8">
上記のようになっていた記述を次のように書き換えてみました。
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
状況変わらず、ダメでした。HTML5では元々のような記述で良いと聞いたことがあったのでこれは期待値低めでした。
・form要素に属性追加
HTMLのform要素に次のような属性を追加しました。
accept-charset='Shift_JIS'
これもダメ。これは初めて聞いたのでもしかしたらと思いましたが、状況変わらず、ダメでした。
2.Servlet
・doPostメソッドの引数にコンテキストタイプ設定
doPostメソッドの引数はHttpServletRequest、HttpServletResponseの型があります。そのどちらに対してもsetContentTypeで文字コードを指定できるとのことでしたので、指定してみました。
request.setContentType("text/html; charset=UTF-8");
ダメでした。次、もう一つの型。
response.setContentType("text/html; charset=UTF-8");
こちらもダメでした。こちらはそもそも返却用なので意味なしです。データを受け取ることがまず出来ていないのですから。
・server.xmlのConnector要素に属性追加
設定ファイルserver.xmlのConnector 要素に属性を追加して文字コードを明示することが出来るとのことで実施してみました。
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"/>
上記のように記載されていたものを次のように編集。
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" />
これもダメ。これをしたときにredirectPortまで削除してしまったようで、構成変えるぞ?のポップアップが表示されました。そのときは何を言われているのかよくわからなかったので、「もちろんOK」としたのですが、これによりリダイレクトすると404エラーが起きるようになってしまいました。ここできちんと文字コードを設定できていたら、課題は解決していたのかもしれません。でもそれは後から気付いたことです、当時はわからなかったことなので仕方がありません(と、自分に言い聞かせてます)。でも皆さんは気を付けてくださいね、この状況を把握して回復させるのに半日くらいかかりました。このおかげでeclipse内部の構成やServletの動きを追うことが出来、大変勉強になりました。結局この方法ではダメだと結論づけて、上記障害を回復させ次第違う解決方法の模索を始めてしまったのですがこの方法で課題解決できる可能性が濃厚です。でも大丈夫、上記の方法での解決を逃してしまっても解決できる方法があります。
3.Filter
最終的に解決した方法です。恥ずかしながらHTMLからJavaへデータを送信する際にフィルターが入ることを私は知りませんでした。フィルタークラスを作成して、そこでコンテンツタイプを指定します。詳細は次の記事にあります。
somegoro.hatenablog.com
これで文字化け問題を無事に解決することができました。
以上、「HTML(form) → Java(Servlet) で文字化けが起きてハマった話」でした。