- PR -

requestパラメータを、画面で指定したcharsetの文字で取得したい

投稿者投稿内容
Edosson
ぬし
会議室デビュー日: 2004/04/30
投稿数: 675
投稿日時: 2005-04-22 18:13
引用:

C ところが、request.getParameterを使うと、戻り値が既にString
  なので(Unicode)Aのチェッククラスが使えない。


これが目的なら、適切なエンコードを指定して、
String#getBytes()でbyte[]を取得して放り込めばいいのでは?
末記入
会議室デビュー日: 2005/03/18
投稿数: 4
お住まい・勤務地: いなか
投稿日時: 2005-04-22 18:32
sekiさん:

Requestのencodingを Windows-31J にして、チェックを行ない、
DBに入れる時に Shift_JIS に変換したらよいのでは??

あとはInputStreamから取得したbyte配列をServletでparseするとか....
coasm
大ベテラン
会議室デビュー日: 2001/11/26
投稿数: 237
投稿日時: 2005-04-24 01:12
「Unicodeに変換される前の元々のバイト列が欲しい」のなら、
エンコード/デコード処理の際に何もしないencodingを指定すれば良いのでは?

request.setCharacterEncoding("ISO_8859_1");
byte[] b = request.getParameter("hogehoge").getBytes("ISO_8859_1");
//文字コードをチェック
String s = new String(b,"Shift_JIS");
つばさ
ベテラン
会議室デビュー日: 2005/02/05
投稿数: 54
投稿日時: 2005-04-24 21:08
つばさです。

Content-Typeですが、
○ファイルアップロードを含む場合
  Content-Type:multipart/form-data
○ファイルアップロードがない場合
  Content-Type:application/x-www-form-urlencoded
です。

サーブレットで、reqをHttpRequestとして
if (req.getContentType() != null &&
req.getContentType().toLowerCase().startsWith("multipart/form-data")) {
//req.getInputStream()でPOSTデータを解析してハッシュなどに設定
//そのときに、クライアントの文字列を変換
}
else {
//request.getParameter("hogehoge");
}
のように取得すればよいと思います。

以上です。
seki
常連さん
会議室デビュー日: 2005/03/23
投稿数: 29
投稿日時: 2005-04-25 20:11
coasmさん:

> request.setCharacterEncoding("ISO_8859_1");
> byte[] b = request.getParameter("hogehoge").getBytes("ISO_8859_1");

→ 上記で、byte配列で取得したbを、ByteArrayInputStreamからInputStream
  へ変換し、見事画面で設定したcharset=Shift_JISで取得できました。

 【Debug】
"@"を画面で入力した時、作成した機種依存文字チェッククラスにて、

SJISチェック------------------>ffffff87
SJISチェック------------------>40

  出来た、と思ったのですが、setCharacterEncodingの指定をFillterを使用して
  実装している為、その画面だけsetCharacterEncoding("ISO_8859_1")を指定
  出来ない事に気がつきました。(他の画面で、〜とかが化ける)

  また、FillterでsetCharacterEncoding("Shift_JIS")を指定しておいて、
  入力チェック該当の画面からのrequestを受け取る前に無理やり再度、
  setCharacterEncoding("ISO_8859_1")を指定しても2重にEncodingするのか
  ちゃんとEncode出来ません。
  
  他の画面は、Fillterでrequest.setCharacterEncoding("Shift_JIS")、
  response.setContentType("Shift_JIS")、JSPもcharset=Shift_JIS
  で統一していたので、〜\‖−¢£¬とか化けなかったのに、新たな問題が
  発生しました。
  
  こっちを直せば、他の部分が駄目になる。
  もはや訳がわからぬ状態です。

_________________
つばさ
ベテラン
会議室デビュー日: 2005/02/05
投稿数: 54
投稿日時: 2005-04-25 23:28
つばさです。

環境はブラウザIE、サーバはWindows+Tomcat4.1.X(JDK1.4.2_X)
でよいのでしょうか?それともLinuxでしょうか。
WindowsがサーバでJDK1.4をお使いでしたら、charset=Windwos-31J
を使用するのが定石かと思います。

ちなみに@をブラウザからPOSTするとブラウザが指定されたページの
charsetでエンコードして、Shift_JISやWindows-31Jなら
key=%87@
のような文字列がサーバーに送信されます。
サーバ側でrequest.getParameter()する際にデコードされますが、
Filterやreqest.setCharterEncodeing()で指定した文字コードでデコード
されますので、エンコードした文字コードとデコードした文字コードが一致
しないとうまくいかないです。

以下のようなかんじになるかと思います。
--------
req.setCharacterEncoding("Windows-31J");
String key = (String)req.getParameter("key");
log.info("@はUNICOEです。key="+key);
StringBuffer buf = new StringBuffer();
for (int j=0; j<key.length(); j++) {
buf.append(Integer.toHexString((int)key.charAt(j)));
}
log.info("@は2460です。HEX(Unicode)="+buf.toString()+"#");
buf.delete(0, buf.length());
//このバイト列でチェック機種依存文字かをチェックすればよかと
byte[] b = req.getParameter("key").getBytes();
for (int j=0; j<b.length; j++){
buf.append(Integer.toHexString((byte)b[j]&255));

}
log.info("@は8740です。HEX(Shift_JIS)="+buf.toString()+"#");
--------
getBytes()したバイト列でファイルアップロードの共通ルーチンを使用されれ
ばよろしいかと思います。
それとWindows-31Jならば、〜\‖−¢£¬は文字化けはしないです。
(Linuxならどうかはちょっとためいしていませんが)
seki
常連さん
会議室デビュー日: 2005/03/23
投稿数: 29
投稿日時: 2005-04-26 11:01
つばささん、遅くに書き込みありがとうございました。

環境はブラウザIE6 SP1、Solaris9、Tomcat5.028、j2sdk1.4.2_06です。

JSPを、charset=Windwos-31J、
request.setCharacterEncoding("Windwos-31J")
response.setContentType("Windwos-31J")
全て"Windwos-31J"にして、ファイル書き込み、読込みも"Windwos-31J"で
byteで取得すると〜\‖−¢£¬、及び@なども文字化けしませんでした。

ただ、今回DBをShift_JISで構築しており、DBにinsertして画面で表示すると
"〜\‖−¢£¬" →"!)\!)!)!)!)!)" 
のように文字化けしてしまいます。

これらの文字はcharset=Shift_JISだとUnicodeのマッピングに問題ないが、
Windwos-31Jだと問題のある文字だと認識しています。
(これらの文字を正しくマッピングするクラスをまた作らなければならない気がします)

今回、お客さんから特に機種依存文字などを使用したいという要望もなく、
文字化けするものはチェックして省いて欲しい、という要望なので
あえてWindwos-31Jを使用しなくても良いと考えております。
(これからはWindwos-31Jじゃないと駄目??)

なので既に作成した、Shift_JISの機種依存文字チェッククラス
を使用して画面からのrequestをチェックしたいのです。

また、教えて頂いたコードを実行すると、

@はUNICOEです。key=@
@は2460です。HEX(Unicode)=2460#
@は8740です。HEX(Shift_JIS)=ada1#

となり、やはり@が、Shift_JISの"8740"として
Hexでも取れません。

もはや、画面でJavaScriptで入力チェックをするしか手段は無いのでしょうか??

_________________
末記入
会議室デビュー日: 2005/03/18
投稿数: 4
お住まい・勤務地: いなか
投稿日時: 2005-04-26 16:55
byte配列の取得する際に明示的に Windows-31J を指定する必要があるのでは??
→ byte[] b = req.getParameter("key").getBytes("Windows-31J");

指定しない場合はSystemのDefault Localeが使用されます。
(SolarisだったらEUCの可能性が高いですね)

スキルアップ/キャリアアップ(JOB@IT)