徒然なるままに

個人の備忘録を中心としたブログです

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
フォームからGETで送られたパラメータをjspで取り出すときに文字化けしてしまう問題が起こった。
というのもtomcat5以降とtomcat7で挙動が変わるらしい。(5より前を今更使い始める人もいないだろう)

この問題を解決するのに参考になったOKwaveの質問ページ
JSP/Servletのパラメータの受け渡しが文字化けしてうまくいきません。

以下、tomcat5についての上記ページからの引用
--------------------------------------------------------------------------------------------------------------------

 Tomcat5では、GETで送られるアドレス部のURL文字列のデコードに、必ずISO8859-1が使われるため、
サーブレット中でSetCharacterEncoding()メソッドにより文字エンコーディングを指定しても、デフォルトではそれが無視されてしまいます。
 Tomcatが悪いわけではありませんが、以前のバージョンのTomcatと振る舞いが異なるため混乱の原因となっています。

このデフォルト値を変更するには、以下の場所にあるserver.xmlを編集する必要があります。

/conf/server.xml

server.xmlを開いたら、次の記述を追加します。
useBodyEncodingForURIの設定(80行目付近)


server.xmlはTomcatの動作を設定するためのファイルです。
UseBodyEncodingForURI="true"を指定することで、
URLデコード時にsetCharacterEncoding()メソッドで指定した文字エンコーディングが使われます。
この設定を行った後、Tomcatを再起動して、再び実行すれば文字化けせずに表示されます。

補足::
・POSTリクエストの場合はこの設定を行わなくても文字化けしません。
これはPOSTではGETと違ってパラメータをURLの一部として送信しないからです。
・サーブレットAPIの将来のリリースではsetCharacterEncoding()メソッドのエンコーディングがアドレス部分に適用されると
明記されるようになる予定なので、この設定を行うのが今のところベターな対処だと考えられます。

[COLUM]
getBytes()のnew String()
setCharacterEncoding()メソッドはサーブレットAPI2.3で導入されました。
それより前には以下のように自前でエンコーディングを行う必要がありました。

String message = request.getParameter("message");
message =new String(message.getBytes("ISO8859-1"),"Shift_JIS");

古い資料を見るとこのようなサンプルソースもあるかもしれませんが、現在はあまり利用されません。

---------------------------------------------------------------------------------------------------------------------

現在、tomcat7ではUseBodyEncodingForURI="true"を書く必要がないらしい。
つまり、setCharacterEncodingで受け取る文字コードを指定するだけでよい。

<%
request.setCharacterEncoding("UTF-8");
String s = request.getParameter("hoge");
%>

の二行のコーディングで済むらしい。


・・・のだが、Ubuntu12.04のFirefoxで実際にやってみるとこのコードだけでは不十分で自前で変換する必要があった。
手持ちの環境によるだろうが、文字化け対策を重ねておくほうがよいという結論になりました。
pageEncodingはページ自身の文字コードの指定です。
tmp.getByte()は引数で渡された文字コードに直したバイト配列を返します。

String()に関してはこちらから
http://docs.oracle.com/javase/jp/1.5.0/api/java/lang/String.html#constructor_detail
-----------------------------------------------------------------------------------------------
public String(byte[] bytes,
String charsetName)
throws UnsupportedEncodingException

指定された文字セットを使用して、指定されたバイト配列を復号化することによって、新しい String を構築します。新しい String の長さは文字セットによって変化するため、バイト配列長と一致しないことがあります。
-------------------------------------------------------------------------------------------------

というわけで雛形はこんな感じ。
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%
request.setCharacterEncoding("UTF-8");
String tmp = request.getParameter("hoge");
String carname = new String(tmp.getBytes("ISO8859_1"),"UTF-8");
%>
<html>
<head><title>タイトル</title></head>
<body>適当</body>
</html>


これだけやれば、まず文字化けは直っていると思います。
自身でいろいろ試すときはURLに「?hoge=ほげ」など適当な文字列を追加することを忘れないこと。
これを忘れるとgetBytesでNullPointExceptionが出て、コンパイルエラーに悩まされます。
スポンサーサイト

kamiyasu

Author:kamiyasu

QR

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。