Java Webアプリ開発における日本語パラメータの文字化け対策
2009/04/03 13:12Update
Java Web開発における日本語パラメータの文字化け対策について学びます。
まず、簡単なサンプルファイルから
submitAsia.html
上のsubmitAsia.htmlをブラウザーで開き、テキストボックスに「日本語だよ」と入力してsubmitボタンを押下します。
すると、ブラウザーのアドレスバーに
file:///C:/submitAsia.html?userName=%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%A0%E3%82%88
のようなURLが表示されます。
ご覧のように、userNameはテキストボックスのid属性で、%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%A0%E3%82%88 は何でしょうか。
簡単なJavaプログラムでテストしてみます。
実行します。以下のような結果が表示されます。
お分かりに なりましたか。
ブラウザーがWebサーバに送ったパラメータの値はjava.net.URLEncoder.encode()メソッドで変換した値と全く同じです。
なるほど、ブラウザーはWebサーバに送信する際に、英数字以外の文字(日中韓国語など)を一旦変換(エンコード)してサーバに送信しているわけですね。
で、日本語パラメータを含んだリンクの場合はどうでしょう。
次のようなサンプルからみてみます。
asiaLink.htm
IEなどのブラウザーでasiaLink.htmを開き、それぞれのリンクを押下します。
すると、リンク2の場合、「Google検索画面」が正常に表示されますが、リンク1の場合の「Google検索画面」が文字化けています。
■結論:
リンクのパラメータに日本語などの文字が含んだ場合、サーバ側に正常に処理させる(文字化けしないようにする)には、エンコードした値をサーバ側に送る必要があります。
1)JSPで書く
2)JavaBeanで書く
3)カスタムタグ
カスタムタグでリンクを出力する際、文字化けの対策としてもjava.net.URLEncoder.encode()でパラメータをエンコードします。
JSPは上の対策を講じる後、文字化けはしないと思われますが、日本語パラメータをServlet側でどう受け取るのでしょうか?
/someServlet?key=%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%A0%E3%82%88
GetAsiaCharServlet.java
※%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%A0%E3%82%88は「日本だよ」のUTF-8でエンコードされた文字です。なので、
※1)で取得したパラメータの文字コードは「ISO-8859-1」であるため、「ISO-8859-1」を「utf-8」に変換する必要があります。
key = new String(key.getBytes("ISO-8859-1"), "utf-8");
ちなみに、Servletで一旦受け取った日本語のパラメータを他のServlet(URL)に転送する場合、再びURLEncoder.encode()で変換(エンコード)する必要があります。
res.sendRedirect("http://www.google.com/search?q="+URLEncoder.encode(key, "utf-8"));
Java Webアプリ開発における文字化け対策 - 概要
submitAsia.html<html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> </head> <body> <form method="get"> <input type="text" name="userName" id="userName"> <input type="submit" value="submit" /> </form> </body> </html>
上のsubmitAsia.htmlをブラウザーで開き、テキストボックスに「日本語だよ」と入力してsubmitボタンを押下します。
すると、ブラウザーのアドレスバーに
file:///C:/submitAsia.html?userName=%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%A0%E3%82%88
のようなURLが表示されます。
ご覧のように、userNameはテキストボックスのid属性で、%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%A0%E3%82%88 は何でしょうか。
簡単なJavaプログラムでテストしてみます。
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
public class EnDecoderUtil {
public static void main(String []args) {
try {
String str = URLEncoder.encode("日本語だよ", "UTF-8");
System.out.println(str);
str = URLDecoder.decode(str, "UTF-8");
System.out.println(str);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
実行します。以下のような結果が表示されます。
c:\>javac EnDecoderUtil.java
c:\>java EnDecoderUtil
%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%A0%E3%82%88
日本語だよ
c:\>java EnDecoderUtil
%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%A0%E3%82%88
日本語だよ
お分かりに なりましたか。
ブラウザーがWebサーバに送ったパラメータの値はjava.net.URLEncoder.encode()メソッドで変換した値と全く同じです。
なるほど、ブラウザーはWebサーバに送信する際に、英数字以外の文字(日中韓国語など)を一旦変換(エンコード)してサーバに送信しているわけですね。
で、日本語パラメータを含んだリンクの場合はどうでしょう。
次のようなサンプルからみてみます。
asiaLink.htm<html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> </head> <body> 日本語パラメータリンク1:<a href="http://www.google.com/search?q=日本語だよ">日本語だよ</a><br> 日本語パラメータリンク2:<a href="http://www.google.com/search?q=%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%A0%E3%82%88">日本語だよ</a> </body> </html>
IEなどのブラウザーでasiaLink.htmを開き、それぞれのリンクを押下します。
すると、リンク2の場合、「Google検索画面」が正常に表示されますが、リンク1の場合の「Google検索画面」が文字化けています。
■結論:
リンクのパラメータに日本語などの文字が含んだ場合、サーバ側に正常に処理させる(文字化けしないようにする)には、エンコードした値をサーバ側に送る必要があります。
JSPのパラメータ・エンコード
1)JSPで書く
<a href="some.jsp?key=<%=java.net.URLEncoder.encode("日本語文字","UTF-8")%>">リンク</a>
2)JavaBeanで書く
<jsp:useBean id="someBean" class="Beans.SomeBean"
scope="request" />
...
<%
String chars = myBean.getSomeProp();
out.println("<a href=\"some.jsp?key=" + chars + ">リンク</a>");
%>
...
3)カスタムタグ
カスタムタグでリンクを出力する際、文字化けの対策としてもjava.net.URLEncoder.encode()でパラメータをエンコードします。
SERVLETで日本語パラメータの受け取る
JSPは上の対策を講じる後、文字化けはしないと思われますが、日本語パラメータをServlet側でどう受け取るのでしょうか?
/someServlet?key=%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%A0%E3%82%88
GetAsiaCharServlet.javaimport java.io.IOException;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GetAsiaCharServlet extends HttpServlet {
@Override
//redir?key=xxxx
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
//1)パラメータの取得
String key = req.getParameter("key");
//2)日本語パラメータの取得
key = new String(key.getBytes("ISO-8859-1"), "utf-8");
System.out.println(keyword);
//...
//3)その他処理
//res.sendRedirect("http://www.google.com/search?q="+URLEncoder.encode(key, "utf-8"));
}
}
※%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%A0%E3%82%88は「日本だよ」のUTF-8でエンコードされた文字です。なので、
※1)で取得したパラメータの文字コードは「ISO-8859-1」であるため、「ISO-8859-1」を「utf-8」に変換する必要があります。
key = new String(key.getBytes("ISO-8859-1"), "utf-8");
ちなみに、Servletで一旦受け取った日本語のパラメータを他のServlet(URL)に転送する場合、再びURLEncoder.encode()で変換(エンコード)する必要があります。
res.sendRedirect("http://www.google.com/search?q="+URLEncoder.encode(key, "utf-8"));
参考資料
Java Webアプリ開発における文字化け対策 - 概要
Sponsored Link
Comments
- Relative Articles
- Java開発及び実行環境の構築 | Linux篇 - (2008/08/31 20:34)
- Java開発及び実行環境の構築 | Windows篇 - (2008/08/31 21:18)
- 5分でJava Hello World! - (2008/08/31 22:13)
- Java言語の制御構文 - 条件分岐if/else/else if - (2008/10/01 21:30)
- Java言語の繰り返し制御構文 - for文 - (2008/10/03 18:22)
- Java言語の繰り返し制御構文 - do ... while文 - (2008/10/03 21:23)
- Java言語の繰り返し制御構文 - while文 - (2008/10/03 21:32)
- Java言語の基礎 - javacコマンドによるコンパイル - (2008/10/10 17:58)
- Java アクセス修飾子概要 - (2008/10/29 18:31)
- Javaアノテーション機能 概要 - (2009/02/12 13:06)