- PR -

ファイルダウンロードの中身の送信

1
投稿者投稿内容
ぼぼ
常連さん
会議室デビュー日: 2005/05/29
投稿数: 45
投稿日時: 2006-04-12 02:22
また質問させてください。

ファイルダウンロードをhtml記述ではなくstrutsのjava内部で実行させようとしていますが
@ダウンロードファイルの中身が常に空(開いた時も)。
A開く保存のダイアログ表示時に開くを押すと同じダイアログがまた表示される。

の2つのエラーが出てしまいます。

web上で見つけたソースを元に作りましたが実際ActionForwardを返していないのも気
になってるのですが・・、分かる方はご指摘ください。
○javaソース
public class AdminDownloadAction extends BaseAction {

public ActionForward perform(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {

// インスタンス生成
AForm tform = (AForm) form;
try {
StreamInfo strInfo = getStreamInfo(mapping,tform,request,response,"DOWNLOADPATH");
} catch (Exception e) {
request.setAttribute("ErrMsg",e.toString());
return (mapping.findForward("error"));
}
return null;
}

protected StreamInfo getStreamInfo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, String infoPath) throws Exception {

AForm tform = (AForm)form;
AData data = (AData)tform.getItemL(Integer.parseInt(tform.getSelectKey()));

String fileName1 = data.getDownloadFileName();
String fileName2 = new String(fileName1.getBytes("Shift_JIS"), "8859_1");

//content typeの取得 activation.jarを利用
FileDataSource fds = new FileDataSource(fileName1);
String contentType = fds.getContentType();
response.setHeader("Content-disposition", "attachment; filename=\"" + fileName2 + "\"");

String path = servlet.getServletContext().getRealPath(infoPath);
File file = new File(path + "/" + fileName1);
return new FileStreamInfo(contentType, file);
}
}

sruts-config.xmlはActionパスを通しているだけです。

よろしくお願いします。
しの
会議室デビュー日: 2006/04/11
投稿数: 5
お住まい・勤務地: 愛知県
投稿日時: 2006-04-12 11:27
@についてですが・・・
StreamInfoを使ってダウンロード機能を提供するのであれば、継承すべきクラスはBaseActionではなく、DownloadActionになるはずです。
もし、BaseActionを利用するのであれば、StreamInfoを利用するのではなく、HttpServletResponseからOutputStreamを取得して、そちらに出力しないとダメだと思います。

Aは、難しい話になると思います。
「struts ダブルクリック」というキーワードでぐぐってみてください。
ぼぼ
常連さん
会議室デビュー日: 2005/05/29
投稿数: 45
投稿日時: 2006-04-12 14:39
しのさんありがとうございます。

@ですがファイルの無い時Exception画面に飛んでしまい、ファイルが無いとのエラー内容画面を表示させたいのですがむりなのでしょうか?(StreamInfoのため)
HttpServletResponseからOutputStreamを取得してこちらのやり方を考えたのですがresponseになくやり方も分かりませんでした。
どんな感じかご教授願えないでしょうか?

Aは他のページでも二重送信制御をしなければと悩んでいました。
javascriptで何とか対応したいと思ってます。

よろしくお願いします。
しの
会議室デビュー日: 2006/04/11
投稿数: 5
お住まい・勤務地: 愛知県
投稿日時: 2006-04-12 16:33
引用:

@ですがファイルの無い時Exception画面に飛んでしまい、ファイルが無いとのエラー内容画面を表示させたいのですがむりなのでしょうか?(StreamInfoのため)


DownloadActionは使ったことが無いので分かりませんが、ソースを見る限りでは、
executeメソッドをオーバーライドして小細工すればできそうです。
(他の手段もあるとは思いますけどね)

引用:

HttpServletResponseからOutputStreamを取得してこちらのやり方を考えたのですがresponseになくやり方も分かりませんでした。


HttpServletResponse(正確には親クラスのServletResponse)に、getOutputStreamというメソッドがあるはずです。
responseに対して適当なContent-TypeとContent-Dispositionを設定し、その後にgetOutputStreamをコールして出力用ストリームを取得すれば、できます。
こちらを参考にされては如何でしょうか?



[ メッセージ編集済み 編集者: しの 編集日時 2006-04-12 16:34 ]
未記入X
大ベテラン
会議室デビュー日: 2005/05/19
投稿数: 136
投稿日時: 2006-04-12 17:03
こんにちは
引用:

ぼぼさんの書き込み (2006-04-12 02:22) より:
A開く保存のダイアログ表示時に開くを押すと同じダイアログがまた表示される。

の2つのエラーが出てしまいます。


とのことですが、以下の私の認識で合っていますか?
1)お使いのブラウザはIE
2)開くを押すと同じダイアログが表示されて、さらに開くを押すと目的のファイルを
  開くことができる

もしこのような場合ですと、このスレッドが参考になるかもしれません
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=5606&forum=12&start=0
ぼぼ
常連さん
会議室デビュー日: 2005/05/29
投稿数: 45
投稿日時: 2006-04-12 18:45
しのさん、未記入さんありがとうございます。

おかげさまでダウンロードファイルの中身の受信はできるようになったのですが、
やっぱりチェック機能でどうしてもだめです。
強引にfindforwardにエラーmappingを突っ込んでみたのですが、やっぱりExcption
画面が表示されてしまいました。

DownloadActionを継承してActionForwardが返り値じゃないので当然と言えば当然ですが・・。
そもそもこのクラスでファイルの存在チェックや例外エラーは組み込めないような気がするんですが・・、もう疲れた・・。
しのさんの紹介していただいたのをこれから参照します、すいません遅れてしまいました。

未記入さんおっしゃる通りでした!
コンテントタイプの指定がいけないようでした、というよりダミーを持たせて回避するなんて
バグですね。
ありがとうございました、ダイアログは出なくなりました!
しの
会議室デビュー日: 2006/04/11
投稿数: 5
お住まい・勤務地: 愛知県
投稿日時: 2006-04-13 10:07
引用:

強引にfindforwardにエラーmappingを突っ込んでみたのですが、やっぱりExcption
画面が表示されてしまいました。



強引に、であれば、こんなコードになるでしょうか?
(動作確認など、行ってませんのであくまで参考程度にしてください。)

コード:
public class SampleDownloadAction extends DownloadAction {
    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response) throws Exception {

        StreamInfo info = null;
        InputStream stream = null;
        try {
            info = getStreamInfo(mapping, form, request, response);
            stream = info.getInputStream();
        } catch (Exception ex) {
            // ファイルが無い場合などに引っかかる。エラー表示処理を入れてください。

        } finally {
            if (stream != null) {
                stream.close();
            }
        }
        
        // 以下はコピー
        try {
            response.setContentType(info.getContentType());
            copy(stream, response.getOutputStream());
        } catch (Exception ex) {
            // ダウンロード中にエラー。エラー画面表示は不可。
            
        } finally {
            if (stream != null) {
                stream.close();
            }
        }
        return null;
    }

    protected StreamInfo getStreamInfo(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response) throws Exception {
        String contentType = "application/octet-stream-dummy";
        File file = new File(mapping.getParameter());
        return new FileStreamInfo(contentType, file);
    }
}



Aのほうに関しては、完全に認識がまちがっていました。
申し訳ありません。
ぼぼ
常連さん
会議室デビュー日: 2005/05/29
投稿数: 45
投稿日時: 2006-04-16 04:57
しのさん!!ありがとうございます。

しばらくこちらを見てなかったのは違う方法(一覧でダウンロードファイルのチェックをし存在のないのは押せないようにするなど・・)を考えていました。
ただ、しのさんのソースを試して見ましたら出来ました!!

ぼくがやっていたのはエラーチェックで引っかかったのはmappingにセットするだけのものでした。
わざわざサンプルソースを書いていただきありがとうございます、本当に感謝です!

そこでサンプルソースの気になった個所ですが、はじめのtry-catchのfinallyのstreamは閉じない(copy()で使う為)という事と、エラー画面表示の不可も出来ました!
こちらはjspにもよりますが汎用的にエラー画面を表示できる仕組みであれば
request.setAttribute("Err","ダウンロード中にエラーが発生しました。");
return (mapping.findForward("error"));
で行けました(strutsなら当然ですが・・)。

返事が送れて申し訳ありませんでした、また本当にありがとうございました!
1

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