JSP.文字コード


この文字列がPOSTのボディ部分 ( POST は Body に組み込まれる ) 日本語の場合は歴史的な経過から文字エンコーディングが複数存在する 現在はMicrosoftが開発しWindows系で一般的に採用されている Shift_JIS と呼ばれるもの POINT win32 環境では SJIS が一般的 Linux系で一般的に採用されてい る EUC-JP の2つのエンコーディング双方が利用 WebSphere はShift_JIS がデフォルト WTE のサーブレット・エンジンもクライアントから URLエンコードで送られてきたパラメタ(バイト列)を Shift_JISの文字コード列だと見なしてこれをJavaのUnicodeに変換する WTE の環境では クライアントがEUC-JPで要求パケットを送ってくると問題 WebSphere のアプリケーション・サーバでは設定ファイルの デフォルトの クライアント・エンコーディングを変更してこれに対応することになる これ以外にもPOST要求でHTTP要求のボディ部分に クライアントからのパラメタを書き込ませ これをバイトごとに読み出してEUC-JPとしてUnicodeに変換する手段もあるが一般的ではない WTEの環境ではクライアントから必ず Shift_JISでエンコードされた要求が到来するようにすることが推奨される サーバに情報を送信するためのフォームを含む HTML ドキュメントが表示され ユーザがその画面の送信ボタンをクリックして必要な情報をサーバに送信する際 POINT IE, Netscapeのブラウザは HTML文書の文字コードを使ってバイト列を作成し、URLエンコードする クライアントに渡すフォームを含む HTMLドキュメントには以下の要素を含めることが必要 これは SJIS でかかれてまよ ! と宣言する そして SJIS として URLEncode される <META HTTP-EQUIV="Content-Type" CONTENT="text/html;charset=Shift_JIS" > 更にサーブレットからそのような画面をクライアントに返すときは エンジンに変換する文字エンコーディングを明示的に指示するだけでなく クライアントに HTTP 応答パケットのヘッダ行で使用文字エンコーディングをはっきり通知すべき response.setContentType("text/html; charset=Shift_JIS"); // 応答ヘッダContent-Type行追加 Websphere のエンジンはShift_JISでエンコードされた要求パラメタは正しくUnicodeに変換してくれている Tomcat のエンジンはそれほど親切ではない このサーブレットは Tomcat のコンテナで走らせると漢字は正しく表示されない 変換する前の文字コードは ISO8859_1(Latin-1) であると仮定して 8859_1 から Unicode への変換テーブルを用いて String 型 のオブジェクトにしてしまう ここが Java の Default の操作 POINT JAVA は URL を decode するときに "8859-1" として仮定していること -> それを UNICODE に変換する Byte --> 8859_1 --> request.getParameter( "xxx" ) ---> getBytes( "8859-1" ); ---> 指定した文字コードに変換しろ となる ( Java の勝手な解釈 ) もう一度 バイトコードをくれ getBytes( "8859-1" ) これをもとに Shift_JIS や EUC-JP の文字列が URLエンコード されてくると 対応した 正しい Unicode の文字列が得られない String correctName = new String(name.getBytes("8859_1"), "Shift_JIS"); // 指定文字コードに対応した Byte 列をかえす getBytes(String charsetName) 指定された文字セットを使用してこの String をバイトシーケンスに符号化し 結果を新規バイト配列に格納します // HttpRequestDumpの要求パラメタの出力部分を // Tomcat用に変更する
out.println(); out.println("要求パラメタ:"); // すべての Parameter を列挙する Enumeration paramNames = request.getParameterNames(); while ( paramNames.hasMoreElements() ) { String name = (String) paramNames.nextElement(); String[] values = request.getParameterValues( name ); // out.println(" " + name + ":"); // Tomcatの場合は上の1行は以下の2行のように変更し 日本語の文字化けに対応すること // TomcatはURLエンコードされているパラメタのコードが // 標準のISO8859_1(Latin-1)であると仮定し // それを単にStringに(つまりUnicodeで)格納して // 各サーブレットにわたす // そのためパラメタ文字列を取得するときに // ISO8859_1から自分が期待する WARNING 短いデータではJISAutoDetectは正しく機能しない
String correctName = new String(name.getBytes("8859_1"), "Shift_JIS"); out.println(" " + correctName + ":"); for (int i = 0; i < values.length; i++) { try{ // out.println(" " + values[i]); // Tomcatの場合は上の1行も同様に以下の2行のように変更すること String correctValue = new String(values[i].getBytes("8859_1"), "Shift_JIS"); out.println(" " + correctValue); }catch(Exception e){ System.out.println("URL Decoding Error"); } } }
// これは失敗する 8859_1 という文字セットは8ビット単位なので Unicodeの1文字は確実に8859_1の1バイト (null(%00)も含めた256文字)に1対1で対応しており問題が生じなかった WTE の SJISコンバータは 変換できないバイトは無視してしまうので そのような逆操作をしても元には戻らない
  CommandPrompt   JScript   sql   Cygwin   Emacs   Make   Python   OpenGL   ss   Csharp   Winsock   net   thread   pro_tip   win   lua   blender