http://mergedoc.sourceforge.jp/tomcat-servletapi-5-ja/javax/servlet/ServletRequest.html#setCharacterEncoding(java.lang.String)setCharacterEncoding
void setCharacterEncoding(java.lang.String env) throws java.io.UnsupportedEncodingExceptionこのリクエストのメッセージボディで使われている文字エンコーディング名を上書きします。 このメソッドはリクエストのパラメータを読み込む前に、また getReader() メソッドを使って入力ストリームから読み込む前に実行されなければなりません。
というわけなので、今回のStrutsの脆弱性対応のFilterなどrequestのパラメタを読み込むフィルターをsetCharacterEncodingするフィルターの前に入れてしまうとうまくいかなくなる。
これはパラメタの値だけでなくパラメタ名を読み込む場合でも同じらしくgetParameterNames()などをつかうとsetCharacterEncodingがうまく実行されない。
Tomcat6のコードだとこんな感じ
public Enumeration getParameterNames() { if (!parametersParsed) parseParameters(); return coyoteRequest.getParameters().getParameterNames(); }
事前にparametersParsedでパラメタがparse済みかどうかチェックして、parseParameters()で文字コードを設定している
protected void parseParameters() { parametersParsed = true; Parameters parameters = coyoteRequest.getParameters(); // Set this every time in case limit has been changed via JMX parameters.setLimit(getConnector().getMaxParameterCount()); // getCharacterEncoding() may have been overridden to search for // hidden form field containing request encoding String enc = getCharacterEncoding(); boolean useBodyEncodingForURI = connector.getUseBodyEncodingForURI(); if (enc != null) { parameters.setEncoding(enc); if (useBodyEncodingForURI) { parameters.setQueryStringEncoding(enc); } } else { parameters.setEncoding (org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING); if (useBodyEncodingForURI) { parameters.setQueryStringEncoding (org.apache.coyote.Constants.DEFAULT_CHARACTER_ENCODING); } } ... }