Mamoru WATANABE
mamor****@hotma*****
2002年 12月 19日 (木) 16:42:15 JST
渡辺です。 私もTurbineの中を調べてみました。解説になってしまって長くなりますが... > > 実はHTMLフォームを使った場合のContent-Typeはほとんどが(HTMLの<form>タ > > グのデフォルトのenctype属性がapplication/x-www-form-urlencodedだから) > > application/x-www-form-urlencodedになるため、既にエンコード済みのもの > > であるから、Content-Typeにcharset=xxxxxとは付ける必要がなく(エンコー > > ド済みの文字列にはUS-ASCII以外の文字が入らないから)、結果として > > Request.getCharacterEncoding()では値をとってこれず、常に"US-ASCII"に > > なってしまいます。 > > Turbine の方を確認したのですが、US-ASCII が入るのは、RunDataFuctory で > new DefaultParameterParser() としていて、BaseValueParser で recycle() > が実行されると、強制的に US-ASCII をセットしているためだと思います。 > なので、recycle() で US-ASCII をセットするのではなく、characterEncoding > を使わないのが問題ではないでしょうか。正しくは、new DefaultParameterParser > (String enc) を実行して、recycle() で characterEncoding を使用することが > 良い気がしています。(でも、おっしゃるとおり、BaseValueParser が機能して > いないのでだめな気がしますが・・・) 確かにrecycle()でUS-ASCIIにセットしていますが、そもそもrecycle()メソッ ドを呼び出すのはPoolServiceで行われているようです。 Turbineのフレームワークを利用した場合、リクエストの受付は全てMVCで言う ところのコントローラであるTurbineサーブレットが行っており、このTurbine サーブレットでは、リクエストが来る度にRunDataFactoryを使ってRunDataを 取得しています。これはTurbineサーブレットがRunDataを作り出すのではなく、 ほとんどの場合RunDataServiceを通してPoolServiceからプールされている RunDataを取り出しています。この時にRunDataServiceを通してPoolServiceか らRunDataを取ってこれなかった場合のみに、 data.setParameterParser(new DefaultParameterParser()); としてDefaultParameterParserをnewしているようです。普通に RunDataServiceを通じてRunDataを取得する場合にはTR.pに記述されている ParameterParserをセットしています。 では、プールから取り出されて活性化したRunDataのParameterParserにある characterEncodingという変数に値をセットするのは何時かというと、 HelloAction.java等の中で、現在問題になっているコードである rundata.getParameters() という部分で、RunDataが保持しているRequest情報をParameterParserに渡す ために、ParameterParserのsetRequest(HttpServletRequest req)メソッドを 呼んでおり、このメソッドの中で渡されたRequest情報からCharacterEncoding を取得してそれをセットしています。 ところが先のメールにも書いたように、このsetRequestメソッドでエンコーディ ングを取得しようとしても、HTMLフォームの場合にはRequestヘッダの Content-Typeフィールドにはapplication/x-www-form-urlencodedがあって、 charsetの指定が含まれていないため、エンコーディングは常にUS-ASCIIになっ てしまいます。 ついでに使い終わったRunDataは、最後にTurbineサーブレットによって、取り 出した時と同じ経路でPoolServiceに戻されます。 多分このプールされる(されている?)時にrecycle()メソッドが使われてい るのではないかと思います。もしかしたらRunDataがプールから取り出されて 活性化している段階で、ユーザがrecycle()メソッドを呼び出すのは掟破りな のかもしれません。 -- 渡辺 衛 mamor****@hotma*****