struts+jQuery Form Pluginを使ったファイルアップロード②〜IEの動作〜
前回、タイトルの通り、画像ファイルをアップロードして
元の画面に表示するという処理を書きました。
struts+jQuery Form Pluginを使ったファイルアップロード① - わたしの日記だよ
ただ、IEのときだけActionが呼ばれないことがあったので
以下のように確認してみました。
1.レスポンスの確認
まず、ieHTTPHeaders使って、そもそも応答が来てるかどうか調べます。
IE8だと、元々は入ってないので、別途インストールが必要です。
使い方は、IEブラウザの
Tools → Explorer Bars → ieHTTPHeaders を選択後、確認したい通信を実行するだけです。
今回は、HTTPステータス200:OKが返ってきていました。
一応、正常に返ってきたことにはなっているのか。。。
2.Actionの前に呼ばれる処理
Struts2にはインターセプターという仕組みがあり、リクエストが投げられると
このインターセプターが呼ばれた後、Actionへ処理が渡ります。
たくさん種類がありますが、
Validationインターセプター(名前のとおり、バリデーション処理を行う)
Servlet Configインターセプター(サーブレット関連の値をセットする)
なんかが、イメージが湧きやすいでしょうか。
自前で用意することも可能です。
まずは、Servlet Configインターセプターが呼ばれているか、確認します。
Actionクラスで「なんとかAware」インターフェースを実装して使用します。
今回は
ServletRequestAware、ServletResponseAware、SessionAware
の3つを使っていたので、ServletRequestAwareのメソッドにブレークポイントを
置いて、アップロードを実行してみました。
他のAwareのメソッドも含め、ちゃんと呼ばれていました。
次に、その他のインターセプターを確認します。
Actionクラスにアノテーションで指定されています。
@InterceptorRefs({ @InterceptorRef(value = "myDefaultStack") }) public class TestAction extends ActionSupport { ・・・
こんな感じ。@InterceptorRefの値「myDefaultStack」はstruts.xmlの中で
設定されています。
<package name="attend-reserve" extends="struts-default"> <interceptors> <interceptor name="myInterceptor" class="xx.xxx.MyInterceptor" /> <interceptor-stack name="myDefaultStack"> <interceptor-ref name="defaultStack" /> <interceptor-ref name="myInterceptor" /> </interceptor-stack> </interceptors> ・・・ </package>
Actionクラスで指定している「myDefaultStack」では、
defaultStack(struts2のデフォルトインターセプター)と
myInterceptor(自前のインターセプター)を呼ぶよう指定しています。
myInterceptorの最初と最後でログを吐くようにしてみましたが、全然出力されませんでした。
そこで、myInterceptorとdefaultStackの順番を入れ替えたところ
ログ出力されたので、defaultStackで引っかかってるみたい!!
しかし、defaultStackを削除して、アップロードを実行しても
Action側に処理は渡ってきません。
defaultStackの中に、必須のインターセプターが居るのかな??
↓↓↓のページによると、あらかじめ用意されているインターセプターは
struts-default.xmlに定義されていて、defaultStackで使用しているのはそのうち17ほどだそう。
Struts2入門(4)〜インターセプターという仕組み〜:http://codezine.jp/article/detail/3264
多い。。。今回は時間の都合で、これ以上追うのは諦めてしまいました。
3.対策
リクエストが届いていることはわかったので、正常に呼ばれるところで
なんとかすることにしました。
struts2:http://blog.pionet.co.jp/experience/archives/43
formから送信された値がActionの同名フィールドに入ってくるんだな、とは思ってたのですが
<s:property value="フィールド名">などがgetterの呼び出し
<input>タグや<s:textfield>がsetterの呼び出し(name属性=フィールド名)
だったのですね。
getter/setterなしの、publicフィールドを使っていたので気付きませんでした。
前回作ったActionクラスを、以下のように修正しました。
public class TestAction extends ActionSupport implements ServletResponseAware, ServletRequestAware { private static final long serialVersionUID = 1L; // 画面表示用のファイルパス public String imgFileName; // アップロードファイル格納用 private File imgFile; public void setImgFile(File imgFile) { this.imgFile = imgFile; // リクエスト取得 HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(org.apache.struts2.StrutsStatics.HTTP_REQUEST); // 保存するファイル名(一時保存されたファイルは、形式にかかわらず「.tmp」なので「.jpg」に変更) String fileName = imgFile.getName().replace(".tmp", ".jpg"); // 保存用のディレクトリ(/test)をチェックして、存在しなければ作成 File tmpDir = new File(request.getServletContext().getRealPath("/test")); if (!tmpDir.exists()) { tmpDir.mkdir(); } // ファイルを保存 BufferedImage img = null; boolean result = false; File writeFile = new File(request.getServletContext().getRealPath("/test/" + fileName)); try { img = ImageIO.read(imgFile); result = ImageIO.write(img, "jpg", writeFile); } catch (Exception e) { e.printStackTrace(); result = false; } // 保存に成功したら、画面表示用のパスをセットする if (result) { imgFileName = "test/" + fileName; } } public String execute() throws Exception { // 念のため、こっちでもセットしておく if (imgFile != null) { // リクエスト取得 HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(org.apache.struts2.StrutsStatics.HTTP_REQUEST); // 保存された(はずの)ファイル名(一時保存されたファイルは、形式にかかわらず「.tmp」なので「.jpg」に変更) String fileName = imgFile.getName().replace(".tmp", ".jpg"); // 保存ファイルの存在チェック File writeFile = new File(request.getServletContext().getRealPath("/test/" + fileName)); if (writeFile.exists()) { // ファイルが存在していたら、画面表示用のパスをセットする imgFileName = "test/" + fileName; } } return "success"; } ・・・ }
画像ファイルが送信されてきたときの処理を、まるまるsetterに移して
念のため、execute()でも画像表示用のパスのセットだけ行っています。
これで、IEでも毎回画像のアップロード〜表示が行えるようになりました。
あんまりすっきりしないけど、めでたし②!!
それにしても、今さらstruts入門することになるとは。。。