2009-10-29 5 views
7

PHP中間層からJ2EEを理解するJavaバックエンドにパラメータを渡そうとしています。私はGroovyにコントローラコードを書いています。そこには、おそらく国際文字を含むいくつかのパラメータをデコードしようとしています。utf-8をJavaでデコードする

これまでのところ、この問題をデバッグした結果に本当に困惑しています。そのため、誰かが自分の結果を正しく解釈できるように、私はあなたと共有したいと思っていました。

私の小さなテストのために、私が渡しているパラメータは "デジューナー"です。念のために、のSystem.out.printlnは(「Dejeunerの」)は正しく私与える:

今すぐ次のコンソールに

déjeuner 

は、元の文字列の各文字の文字/ 12月と進値であり、私はstmt.geのように、UTF-8文字列としてこの文字列を読みしようと今http://www.fileformat.info/info/unicode/char/00e9/index.htm

:UTF-8でc3a9シーケンスが望んだ-の文字であることを

next char: d 100 64 
next char: ? -61 c3 
next char: ? -87 a9 
next char: j 106 6a 
next char: e 101 65 
next char: u 117 75 
next char: n 110 6e 
next char: e 101 65 
next char: r 114 72 

ノートTバイト( "UTF-8")次のように、私は突然、11のバイト配列を有する終わる:

64 c3 83 c2 a9 6a 65 75 6e 65 72 

stmt.getBytes( "ISO-8859-1")、一方は私9つのバイトを与えます

64 c3 a9 6a 65 75 6e 65 72 

ここでc3a9シーケンスに注意してください!

next char: d 100 64 
next char: ? -61 c3 
next char: ? -87 a9 
next char: j 106 6a 
next char: e 101 65 
next char: u 117 75 
next char: n 110 6e 
next char: e 101 65 
next char: r 114 72 

ノートc3a9シーケンス

をしばらく:今私は私が手

new String(stmt.getBytes("UTF-8"), "UTF-8"); 

にとして、UTF-8にUTF-8シーケンスを変換しようとした場合

new String(stmt.getBytes("iso-8859-1"), "UTF-8") 

結果:

next char: d 100 64 
next char: ? -23 e9 
next char: j 106 6a 
next char: e 101 65 
next char: u 117 75 
next char: n 110 6e 
next char: e 101 65 
next char: r 114 72 

utf-8(とascii)の中のe9は、私が憧れている 'é'文字です。

いずれにしても、リテラル文字列 "déjeuner"のように表示される適切な文字列にはなりません。不思議なことに、バイトシーケンスはどちらも正しいようです。

答えて

9

文字列を扱うときは、常に覚えておいてください:byte!= char。最初の例では、ではなく、があります。byteはUTF-8シーケンスの一部ですが、charは既にUnicodeです。したがって、UTF-8に変換すると、Unicode文字c3byteシーケンスc3 83になります。

質問は次のとおりです。文字列はどのように取得しましたか?UTF-8でエンコードされたbyteシーケンスを適切に処理しないコードにバグが存在する必要があります。

ISO-8859-1が通常動作理由は、この符号化は、コードポイント< 256(0と255との間、すなわち何か)で任意charを変更しないということであるので、UTF-8は、byte配列が改変されない符号化されました。

あなたの最後の例も間違っています:char e9ISO-8859-1とUnicodeでéです。 UTF-8では、byteではないし、byte c3の接頭辞がないので、無効です。つまり、あなたが求めるUnicode文字列を正しく表しています。

+0

非常に有益な回答ありがとうございます。だから、javax.servlet.http.HttpServletRequestのrequest.getParameter()が、UTF-8でエンコードされたバイトシーケンスを正しく処理しないということになります。 私はreq.setCharacterEncoding( "UTF-8")を呼びました。 残っている可能性のある回避策はありますか?それは私のパラメータ(文字ではなくバイト)の元のデータを取得する方法は私にはまだ明らかではないので、私はいくつかの_non-buggy_ Stringの実装を取得して、正しいUTF文字列を取り出すことができます... – user162346

+0

私の推測では、送信者はUTF-8でデータをエンコードしますが、正しいHTTPヘッダーを設定することはできません。 –

+0

PHPの部分が、特にフォームのエンコーディングを正しく指定するWebページを生成することを確認してください。 –

1

Java文字列で始まる場合、"d\u00C3\u00A9jeuner".equals(stmt)の場合、この段階でデータはすでに破損しています。

A Java charはC charではありません。 Javaのcharは幅が16ビットで暗黙的にUTF-16エンコードされたデータを含んでいます。他のエンコードされたデータをJava char/String型で格納しようとすると、問題が発生することがあります。その他のエンコーディングの文字データは、byteデータである必要があります。

parameter using the servlet APIを読んでいる場合、HTTP要求に一貫性のない、または不十分なエンコード情報が含まれている可能性があります。呼び出しコードとHTTPヘッダーを確認します。クライアントがデータをUTF-8としてエンコードしている可能性がありますが、サーブレットはそれをISO-8859-1としてデコードしています。

0

私のフォームが「POST」リクエストではなく「GET」リクエストを使用する点を除いて、私は非常に似た問題を抱えています。

だから、私のURLのようなものです:ブラウザはありませんので、だから、HttpServletRequestのは、(明確にそうでないもの)の要求のparamをデコードするUTF-8を使用する必要がありますか、これは単に、ブラウザのエラーですhttp://localhost:4502/form.jsp?query=d%C3%A9jeuner

request.getCharacterEncoding() = ISO-8859-1 
response.getCharacterEncoding() = UTF-8 
request.getParameter("query") = déjeuner 

どんな文字エンコーディングヘッダーも設定しないでください(それはポストリクエストをしていないのでもう一度意味をなさない)。ここではヘッダの完全なセットがあり、URLに%C3%A9があることに注意してください。

http://localhost:4502/form.jsp?query=d%C3%A9juerne 

GET /form.jsp?query=d%C3%A9juerne HTTP/1.1 
Host: localhost:4502 
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.0.17) Gecko/2010010604 Ubuntu/9.04 (jaunty) Firefox/3.0.17 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: en-gb,en;q=0.5 
Accept-Encoding: gzip,deflate 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 
Keep-Alive: 300 
Connection: keep-alive 

この問題は、実際にはブラウザのフォームにクエリをコピーして貼り付けているために間違ってエンコードされてしまうことです。クロムとファイアフォックスの両方。

0

いくつかのさらなる調査の後、私はこの答え

How to get UTF-8 working in Java webapps?

を見つけました。

これは、tomcatコネクタにURIEncoding = "UTF-8"を設定することです。

ここでは、CMSでこれを行う方法(CQ5 /日)について説明します。

+0

こんにちは、私はStackoverflowで歓迎!他の質問に自分の質問を回答として投稿しないでください!彼らは騒音で迷子になり、誰もあなたの質問に答えません。右上にある「Ask Question」ボタンをクリックして質問を投稿してください。これを済ませたら、このトピックからもこのノイズを削除してください。 – BalusC

関連する問題