1

間違った URI エンコーディングで奇妙な問題が発生しました。助けていただければ幸いです。

このプロジェクトでは、JSP、サーブレット、Jquery、Tomcat 6 を使用しています。

JSP の文字セットは UTF-8 に設定され、すべての Tomcat コネクタは URIEncoding=UTF-8 を使用し、こちらで説明されているように文字エンコーディング フィルターも使用します。また、メタ タグに contentType を設定すると、ブラウザはそれを正しく検出します。

Jquery を使用した Ajax 呼び出しでは、URL パラメーターとして使用したい条件で encodeURIComponent() を使用してから、パラメーター セット全体を $.param() でシリアル化します。呼び出されたサーブレットでは、これらのパラメーターは Java.net.URLDecoder.decode(term, "UTF-8") で正しくデコードされます。

一部の場所では、JSP のパラメーター マップから href 要素の URL を生成しています。各パラメーター値は、JSP 側で Java.net.URLEncoder.encode(value, "UTF-8") でエンコードされますが、以前と同じ方法でデコードすると特殊文字が壊れます。代わりに、JSP で「ISO-8859-2」としてエンコードし、サーブレットで「UTF-8」として正しくデコードする必要があります。

明確にするための例: 「überfall」という用語は、Javascript (%C3%BCberfall) を介して URI エンコードされ、デコードおよび処理のためにサーブレットに送信されます。それを JSP に戻した後、UTF-8 としてエンコードし、URL を作成します。たとえば、次のようになります。

<a href="/myWebapp/servletPath?term=%C3%BCberfall">Click here</a>

ただし、このリンクをクリックすると、パラメータが「%C3%83%C2%BCberfall」としてサーブレットに送信され、「überfall」にデコードされます。エンコードが行われない場合も同様です。

エンコーディングに「ISO-8859-2」を使用すると、次のようになります。

<a href="/myWebapp/servletPath?term=%FCberfall">Click here</a>

このリンクをクリックすると、Wireshark で %C3%BCberfall がパラメーターとして送信され、"überfall" に再度デコードされることがわかります。

誰かが私が何かを逃した場所を教えてもらえますか?

編集: Firebug の [ネットワーク] タブを観察しているときに、

$.param({term : encodeURIComponent(term)}); 

この用語は UTF-8 で 2 回エンコードされ、"%25C3%25BCberfall" になります。つまり、パーセント記号もパーセントでエンコードされます。同様に、パラメータ マップの各値に対して encode(term, "UTF-8") を 2 回呼び出すと、うまくいきます。

String を 1 回エンコードしてデコードしないと、再び "überfall" が発生します。

4

2 に答える 2

1

私は今、間違いなく問題を解決したと思います。

Jontro のコメントに従って、すべての URL パラメータ値を一度エンコードし、サーブレット側の手動デコードを削除しました。

送信は、サーブレットで私を与えたFirebugの[ネットワーク]タブのüように見えるはずです。Java は、-Dfile.encoding パラメーターを使用して "UTF-8" 内部エンコードに確実に設定されていました。このような request.getParameter() メソッドに問題を追跡しました。request.getQueryString は問題ありませんでしたが、実際のパラメーターを抽出すると失敗します。%C3%BCü

request.getCharacterEncoding()) => UTF-8
request.getContentType() => null
request.getQueryString() => from=0&resultCount=10&sortAsc=true&searchType=quick&term=%C3%BC
request.getParameter("term") => × Charset.defaultCharset
() => UTF-8
OutputStreamWriter.getEncoding() => UTF8
new String(request.getParameter("term").getBytes(), UTF-8) => ×
System.getProperty("file.encoding ") => UTF-8

request.getParameter() を実装する Tomcat と Coyote のソースを調べると、問題が見つかりました: コネクタからの URIEncoding は常に null であり、この場合、デフォルトで org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING に設定されます。 8859-1」 ウルフラムが言ったように.

簡単に言うと、Tomcat の conf ディレクトリにある server.xml を編集していたのが原因でした。これは、サーバー ビューで新しいサーバーが作成されたときに Eclipse に一度だけ読み込まれます。その後、Servers プロジェクトの別の server.xml を編集する必要があります。その後、コネクタ設定が正しく読み込まれ、すべてが正常に機能します。

コメントありがとうございます!これが誰かに役立つことを願っています...

于 2012-07-20T08:55:08.727 に答える
1

Java が内部で使用しているエンコーディングは何ですか? でアプリケーションを開始しましたか

-Dfile.encoding=utf-8

「JSP 内のパラメータ マップ」が定義されている場所を明確にしてください。それは永続的なデータストレージからのものですか、それともコードでリテラルとして指定された文字列ですか?

何が起こっているのかについてのいくつかの考えは、役立つかもしれません:

ü各バイトが独自にデコードされたときに、UTF-8エンコードされたものがü期待して読み取られたときに出てくるものです。の両方のバイトのURI エンコード表現です。私はこれが起こっていると思います:ISO-8859-1%C3%BCUTF-8UTF-8 ü

%C3%BC→に誤ってデコードされ、→üにエンコードされ、→%C3%83%C2%BCに再度デコードされるüため、最終的にはüberfall.

したがって、URI でエンコードされた文字列をデコードするために間違ったエンコードを使用していると思います。これは、Java/JVM で使用される内部エンコーディングに関係している可能性があります。

デフォルトでは、JRE 7 インストーラーは、ホスト オペレーティング システムがヨーロッパ言語のみをサポートしていると認識した場合、ヨーロッパ言語バージョンをインストールします。

于 2012-07-16T14:10:28.257 に答える