- - PR -
'%'を文字扱いするとき
1
| 投稿者 | 投稿内容 |
|---|---|
|
投稿日時: 2002-05-16 17:46
お世話になっております。
ある文字列にjava.net.URLEncoderをかけてパラメータにして、 HttpServletRequest.getParameterで受け取るプログラムをつくりました。 ここで、エンコードする文字列に'%'が含まれている場合、 エンコードされたコードは'%25'に変換されるのですが、 これをgetParameterで受け取ったときには'%'になってしまっています。 この現象を防ぐ方法はないでしょうか? ご教授のほどよろしくお願いします。 [ メッセージ編集済み 編集者: ume 編集日時 2002-05-16 19:25 ] |
|
投稿日時: 2002-05-16 19:00
何がやりたいのかがちょっと見えないのですが・・・
おっしゃってる現象はまっとうな挙動ですよね? 1. 文字列「%」を送る 2. エンコードされて「%25」となる 3. getParameterで「%25」と受け取りたい ということでしょうか? だとしたらgetParameterのあとで「%」→「%25」と変換するだけでは。 |
|
投稿日時: 2002-05-16 19:41
ご回答ありがとうございます。
getParameterで受け取った文字列を次にjava.net.URLDecoderにかけているのですが ここで'%'しかないとjava.lang.ArrayIndexOutOfBoundsExceptionがおこります。 java.net.URLDecoder('%25')をすると正常に'%'が返ってくるので '%25'で受け取って使いたいのですが、 getParameterで自動的に変換されているのでしょうか? |
|
投稿日時: 2002-05-16 22:33
はあはあ…やっと根拠らしきもの見つけた。
http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.2 If the Request-URI is encoded using the "% HEX HEX" encoding [42], the origin server MUST decode the Request-URI in order to properly interpret the request. ちうわけで、サーブレットコンテナは decode ずみのものを web app に渡すべき、なんでしょうかね。 # しかし、どんな参考書でも GET の場合は URLDecoder 使えなんて # 書いてない気がするんですけど… # POST と GET でわたってくる形式が違ってたらめんどくさいっすよ。 |
|
投稿日時: 2002-05-17 20:23
>ちうわけで、サーブレットコンテナは decode ずみのものを web app に渡すべき、なんでしょうかね。
># しかし、どんな参考書でも GET の場合は URLDecoder 使えなんて ># 書いてない気がするんですけど… そうですね。Servlet-APIでは、getParameterは必ずURLDecodeした値を返します。 そのため、GETリクエストで送信するURLに漢字などの非ASCII文字列が含まれる 場合は、あらかじめURLEncodeを行っておく必要があるのです。 たとえば、name=ABC と data=漢字 というクエリを送ろうとするなら、 http://hostname/context/page?name=ABD&data=%8a%bf%8e%9a というようにしておきます。 そうすればサーバ側では getParameterで "ABC"、"漢字" が取れます。 (ただし、環境によっては String data1 = new String( data.getBytes("8859_1"), "SJIS"); のような、ワークアラウンドが必要にはなりますが・・・ ) いずれにしましても、POSTと同じインタフェースになるわけです。 URLデコードして復元された値に、さらにURLDecoderをかけたら、冗長処理に なってしまい、元の文字列を壊してしまいます。 K.Nakagome |
|
投稿日時: 2002-05-22 13:37
ご回答ありがとうございます。
>たとえば、name=ABC と data=漢字 というクエリを送ろうとするなら、 >http://hostname/context/page?name=ABD&data=%8a%bf%8e%9a >というようにしておきます。 >そうすればサーバ側では getParameterで "ABC"、"漢字" が取れます。 まさにNakagomeさんのご説明の処理をしようとしています。 getParameterでString型に値を受け取っているのですが 日本語が文字化けして受け取られてしまい、URLdecoderにかけると 正常に受け取ってくれます。 なのでURLdecoderが必要だと考えていたのですが getParameterで日本語が正しく取れないことの方に問題があったのですね。 doPostで画面の入力値を受け取るときにもgetParameterを使っているのですが こちらは正しく受け取っています。 どのあたりに問題があるのでしょうか? たびたびすみませんがアドバイスお願いします。 |
|
投稿日時: 2002-05-22 18:18
> doPostで画面の入力値を受け取るときにもgetParameterを使っているのですが
> こちらは正しく受け取っています。 > どのあたりに問題があるのでしょうか? コンテンツエンコードとプラットフォームのディフォルトエンコーディングの相違の 問題ではないかと思います。 実例をあげて説明します。 プラットフォームがWin32であれば以下のコードが正しく動作するはずです。 ----------------<< from.jsp >>-------------------------------------------- <%@ page contentType="text/html; charset=Shift_JIS" import="java.net.URLEncoder" %> <html><head><title>TEST Page</title></head> <body> <a href="to.jsp?name=ABD&data=%8a%bf%8e%9a">受け取るページへ(リテラル)</a><br/> <a href="to.jsp?name=ABD&data=<%= URLEncoder.encode( "漢字" ) %>">受け取るページへ(URLEncoder)</a> </body> </html> ------------------------------------------------------------------------ -----------------<< to.jsp >>--------------------------------------------- <%@ page contentType="text/html; charset=Shift_JIS" %> <html><head><title>TEST Page</title></head> <body> <a href="from.jsp">戻る</a><br/> <% java.util.Enumeration e = request.getParameterNames(); while(e.hasMoreElements()) { String key = (String)e.nextElement(); String[] values = request.getParameterValues(name); for(int i=0; i < values.length; ++i) { String value = new String( values[i].getBytes("ISO8859_1"), "Shift_JIS") ; if(i == 0) { %> <%= key %> = <%= value %> <% } else { %> ,<%= value %> <% } } %> <br/> <% } %> </body> </html> ------------------------------------------------------------------------ 上の例では、from.jspのリテラルのURLとURLEncoderで処理されたURLが同じに ならなければ、to.jsp側で正しい結果を得ることはできません。 "漢字"をShift_JIS文字エンコーディングでURLエンコーディングされれば %8a%bf%8e%9a になりますが、それ以外の文字エンコーディングでは異なります。 ポイントは、URLEncoderのencode()では、文字エンコーディングを指定できない点に あります。encode()の機能は「文字列を x-www-form-url 符号化形式に変換します。」という 説明がありますが、文字列の文字エンコーディング体系については記述がありません。 したがって、プラットフォームのディフォルト文字エンコーディングで実装されているようです。 ●回避策について 上の原因によるものであれば、回避策としては以下のようなものが考えられます(択一)。 1、J2SDKのURLEncoderを利用する場合、コンテンツのエンコーディングをプラットフォームの ディフォルト文字エンコーディングにあわせる。 2、文字エンコーディングを指定できる自前のURLEncoderを実装し、それを利用してコンテンツと 同一の文字エンコーディングを指定してURLエンコードする。 3、GETとPOSTの処理ロジックを分けて、getParameter()後の文字エンコーディング変換 コード中でプラットフォームのディフォルト文字エンコーディングを指定する。 私はあるプロジェクトで、上の 2の方法を採用しました。 実はそのようなユーテリティを作って、オープンソースで公開している人がプロジェクト内に いまして(Mr.westbay)、彼のパッケージを利用したという経緯でした。 http://sourceforge.net/projects/juli/ jp.co.beacon_it.utils.StringUtil.classのなかのencodeEscape()メソッドです。 K.Nakagome [ メッセージ編集済み 編集者: nakagome 編集日時 2002-05-23 10:54 ] |
1
