Strutsとcommons fileuploadのお話
みんな大好きStrutsのお話。対象VerはStruts1.1です。
commons fileupload
commons fileuploadはStruts1.1標準の1.0。
ファイルをアップロード(Multipart)した際、Struts側ではFormFileが利用されています。
ファイルの情報を持つオブジェクト→FormFileといった感じです。
このFormFile、commons-fileuploadを利用して生成されます。
流れは以下
RequestProcessor#populate → RequestUtils#populate → MultipartRequestHandler#handleRequest → DiskFileUpload#parseRequest →
MultipartRequestHandler#addFileParameter
ソースを読むとわかりますが、
「commons-fileupload:FileItem → Struts側:FormFile」な形でラップしています。
※FileItemはファイル情報用のオブジェクトではありません。
MultipartRequestWrapperとCommonsMultipartRequestHandler
Multipartなリクエストの場合、HttpServletRequestはMultipartRequestWrapperとしてラップされます。
そして注目すべきは以下のメソッド。
/** * This method does nothing. To use any Servlet 2.3 methods, * call on getRequest() and use that request object. Once Servlet 2.3 * is required to build Struts, this will no longer be an issue. */ public void setCharacterEncoding(String encoding) { ; }
RequestProcessorを継承したクラスやprocessPreprocessなんかでMultipartRequestWrapper#setCharacterEncoding
を呼び出すと、エンコード指定が無視されます。
そしてCommonsMultipartRequestHandlerの以下のメソッド。
protected void addTextParameter(HttpServletRequest request, FileItem item) { String name = item.getFieldName(); String value = null; try { value = item.getString(request.getCharacterEncoding()); } catch (Exception e) { value = item.getString(); } ・ ・
item.getStringがnullとなり、item.getString()が呼ばれます
※FileItem#getStringはプラットフォームのデフォルトエンコード設定となります。
怖いですね、これ。
依存ライブラリ変更せず、Struts1.1そのまま使ってればこの設定になります。
画面側のエンコードは基本UTF-8なので、問題無く動いているように見えるだけです。
さいごに
Strutsは使うのやめましょう