日本語Form入力
まずは日本語Form入力。
servletで、GETやPOSTで送られてくるパラメータを取得するには、
request.getParameter("text");
と、やりますが、ディフォールとのままでは、日本語のパラメータは化けてしまいます。
なので、例えばWindows-31J*1のページから投稿された場合、リクエストを処理する一番最初に、、、
request.setCharacterEncoding("Windows-31J");
とエンコーディングを設定してから取得すると、ちゃんと取得できます。(Servlet2.3-API以降)
Servlet2.2-API以前には、、、
value = request.getParameter("text"); value = new String(value.getBytes("iso-8859-1"), "Windows-31J");のようにして、1つひとつ値を変換していたようです。
調子に乗ってこんなコードを書いてみたら動きません。
String encoding = request.getParameter("encoding"); if (encoding == null) encoding = "Windows-31J"; request.setCharacterEncoding(encoding); String searchText = (String) request.getParameter("SearchText");
ようするに"encoding"と言うパラメータを用意して、その内容にしたがってsetCharacterEncoding()しようとしたのですが、なぜか、ENCTYPE="multipart/form-data"でPOSTしたときにだけ、日本語が取得できて、あとは"multipart/x-www-form-data"の時やGETの時には文字化けしてしまいます。
なぜでしょう。
Servletのrequest.setCharacterEncoding()のJavaDocを見ると、、、
This method must be called prior to reading request parameters or reading input using getReader().
なので、ようするに、request.setCharacterEncoding()をする前にrequest.getParameter()を呼んでいると、無効になるのですね。(エラーにしてくれればいいのに、、、)
先にJavaDocをよく読んでおけばよかったです、、、
ちなみに、上のようなことをしたいときには、まず、、、
String encoding = request.getParameter("encoding");を読んだ後に、Servlet2.2-APIの頃の方法と同様に、、、
String value = request.getParameter("PARAM"); value = new String(value.getBytes("iso-8859-1"), encoding);として一つ一つ変換して行く必要があるようです。(これ用にStrutsのDynamiyActionForm等をサブクラスしてあげると良いかも。)
実例1
StrutsのActionServletをサブクラスする場合。/** * 日本語FORM入力をハンドルするためのActionServletクラス。 * */ public class JapaneseActionServlet extends ActionServlet { /** * 日本語FORM入力をハンドルするためのActionServlet.process(). * requestにsetCharacterEncoding()することで以降のgetParameter()からの日本語 * パラメータを、文字化けさせずに変換する。ここではShift_JIS(Windows-31J)で * 書かれたページからのFORM投稿を想定している。 * */ protected void process(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws java.io.IOException, javax.servlet.ServletException { request.setCharacterEncoding("Windows-31J"); super.process(request, response); } }
これに対応するようにweb.xmlも変更する。
action path.to.JapaneseActionServlet ...
実例2
Servlet2.3-APIからは、Servletの処理の前に処理される、Filter機能が追加された。このFilterでsetCharacterEncoding()する物を作れば、複数のServletがあるWebAppにも適応できる。/** * 日本語FORM入力をハンドルするためのServletFilter用クラス。 * */ public class EncodingFilter implements Filter { /** * 日本語FORM入力をハンドルするためのFilter.doFilter(). * requestにsetCharacterEncoding()することで以降のgetParameter()からの日本語 * パラメータを、文字化けさせずに変換する。ここではShift_JIS(Windows-31J)で * 書かれたページからのFORM投稿を想定している。 */ public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setCharacterEncoding("Windows-31J"); chain.doFilter(request, response); } public void init(FilterConfig arg0) throws ServletException { // do nothing. } public void destroy() { // do nothing. } }
このFilterを使うためのweb.xmlファイル設定は、、、
EncodingFilter path.to.EncodingFilter EncodingFilter *
追記メモ
tomcatの5.xでGETなFORMでのエンコーディングは、tomcatの設定ファイルservlet.xmlに、、、のように、「useBodyEncodingForURI="true"」を入れておかなければならない。