Java Webアプリ開発における日本語パラメータの文字化け対策

2009/04/03 13:12Update
TAGS: Java | Web | 日本語 | 文字化け | JSP | Servlet | パラメータ

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
日本語だよ

お分かりに なりましたか。
ブラウザーが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.java
import 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アプリ開発における文字化け対策 - 概要

有关作者
Syboos.jp編集長AJavaやオープンソース情報の執筆、Webサイトの開発や運営全般の業務に携わる。

Sponsored Link


Comments

用户名 (required)

Email (will not be published) (required)

URL

Evaluation