質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Struts

StrutsはJava向けのWebアプリケーションフレームです。MVCモデルに基づいており、JSPやJavaサーブレットを組み合わせ、アプリケーション構築時に使用する各機能を提供しています。

Q&A

解決済

4回答

32498閲覧

ファイルの複数ダウンロードについて

kurage

総合スコア18

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Struts

StrutsはJava向けのWebアプリケーションフレームです。MVCモデルに基づいており、JSPやJavaサーブレットを組み合わせ、アプリケーション構築時に使用する各機能を提供しています。

0グッド

3クリップ

投稿2015/07/05 04:02

こんにちは。

web画面でファイルを複数選択し、選択されたファイルをダウンロードする際の実装方法について、お力添えいただきたいと思います。

<使用ツール>
Windows7、IE9、Javascript、Java1.6、struts

<要件>
1.選択したファイルはzipにしない
2.選択できるファイル数に制限はない
3.ファイルサイズは個々で異なる
4.ファイル数分のwindowは開きたくない
5.ファイルの保存はユーザーが行う(ファイル名の変更など)

Javascriptを用いてファイル数分のwindowを開いてダウンロードを行うことはできたのですが、要件4.に該当してしまうので、1画面内で実装したいと考えています。

<% String fileName = (String)request.getParameter("FILE"); %>

<html> <scrpit> function windowReload() { // リクエストにファイル名を設定するメソッドの実行 document.forms[0].method="setFile"; document.forms[0].submit(): } </script> <body onload="windowReload()"> <iframe src='<%= "download.do?FILE=" + fileName %>'> </iframe> </body> </html>

上記のように、一つ目のファイルをwindow.open()実行時にリクエストに指定し、以降はsetFile()を呼び出すようにし、ダウンロード自体はiframeでの「download.do」で実行しようとしたのですが、wineowReload()が呼び出されるたびにダウンロード処理が中断してしまい、処理を行うことができませんでした。

上記処理について、ご教授の程宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

こんちには。

Ajaxでファイルダウンロード用のServletをファイル数分呼び出し、
ファイルダウンロード用のServlet側では、responseにファイルのStreamを直接セットし、
fowardはさせないようにすればできると思います。

投稿2015/07/05 07:21

編集2015/07/05 07:23
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kurage

2015/07/05 13:34

ご回答いただきましてありがとうございます。 ajaxの知識がなく、もう少し質問させていただいてもよろしいでしょうか。 ご回答いただいた方法としては、以下の認識で相違ありませんでしょうか? 1.Javascrpitにてファイル数分のHttpRequestを生成し、ダウンロード用Servletにpostを送信する。 2.ダウンロード用Servletにてファイルを読み込み、streamを返す 上記を試してみたのですが、ダウンロード用サーブレットは実行されるのですがファイルがダウンロードされず、画面が更新されてしまいました。 「responseにファイルのStreamを直接セットし」とありますのは、content-typeなどの指定をServletでは行わないということでしょうか? また、「fowardさせない」という処理はJavascript側で制御を行うものでしょうか? 申し訳ありませんが、ご教授いただければと思います。
退会済みユーザー

退会済みユーザー

2015/07/06 04:00 編集

こんにちは。 >1.Javascrpitにてファイル数分のHttpRequestを生成し、ダウンロード用Servletにpostを送信する。 そちらの認識で問題有りません。 >2.ダウンロード用Servletにてファイルを読み込み、streamを返す こちらの認識に誤りがあります。ファイルの出力先をresponseのStreamにするという意味です。わかりにくくて申し訳ありません。具体的には、responseにgetOutputStreamというメソッドがありますので、ファイルの出力先をそれにします。その際、content-type等もセットして下さい。 「fowardさせない」というのは、Servlet側で画面を返さないという意味になります。 よろしくお願いします。
kurage

2015/07/09 13:59

こんばんは。 教えていただきましてありがとうございます。 教えていただいた内容から実装を行ってみたのですが、想定の処理を行うことができませんでした。 <JSP> for(var i=0; i<ダウンロードファイル数; i++) { $(ボタン).click( function() { $.ajax(){ url:"ダウンロードファイルを所定のディレクトリに生成するサーブレット", data:"画面Form", async:true, cache:false } ).done(function(dataType) { $(iframeのID).src = "ファイルダウンロードを行うサーブレット"?FILE="ファイル名" } ); } ); } JSP内にはダウンロードする分のiframeを定義していて、そこからダウンロード用サーブレットを実行しました。 また、ファイルダウンロード用のサーブレットでは、受け取ったresponseからOutputStreamを取得し、ファイルの内容を設定してwrite()を実行しました。 ファイルダウンロード用のサーブレットはforwardしないように、mapping情報に該当しないnull値で返すようにしました。 上記で実施した結果として、ボタンをクリックしてからファイル数分のリクエストがサーブレット側に渡り、write()の処理が行われているのはデバッグから確認がとれたのですが、画面では最初のファイルのダウンロードしか行われませんでした。 デバッグで1ファイルずつ処理を止め、順に保存をしていくと全てのファイルの保存が可能なのですが、ただ実行すると1ファイルのみとなってしまいます。 そして、実装方法がおかしいのだと思うのですが、何回も実行していると、ダウンロード対象のファイル数以上のリクエストがサーブレットに流れていってしまいます。 (対象が3ファイルである場合、1回目は3、2回目は6・・・どいう感じです) 実装方法などにおかしな点など、お気づきのことがありましたらお教え願えますでしょうか。 何度も申し訳ありませんが、宜しくお願い致します。
退会済みユーザー

退会済みユーザー

2015/07/10 12:24 編集

こんばんわ。 もうちょっとな感じですね。 > また、ファイルダウンロード用のサーブレットでは、受け取ったresponseからOutputStreamを取得し、ファイルの内容を設定してwrite()を実行しました。 ファイルダウンロード用のサーブレットはforwardしないように、mapping情報に該当しないnull値で返すようにしました。 こちらの認識で間違いありません。 あまり関係ないかもしれませんが、貼って頂いたJavaScriptはfor文の位置がおかしい気がします。ボタンをクリックしてからファイル数分のリクエストを飛ばすのであれば、`function() {`の後にくるのではないでしょうか。 ここは未知の領域なのですが、全てのリクエストが全くの同時に飛ぶとダウンロードができないのかもしれません。一時的にajaxのasyncパラメータをfalseにして同期通信で試してもらえないでしょうか。また、多少ディレイ(遅延)とかけるとかしないとだめなのかもしれません。 よろしくお願いします。
kurage

2015/07/13 14:47

こんばんは。 確認が遅くなりまして、申し訳ありません。 for文をfunction(){}の中に入れますと、ループ変数iを正常に参照できなかったため、外へ出して記述を行いました。 また、同期通信、遅延も行ってみたのですが、ダウンロードは1回しか行われませんでした。 画面上でボタンを数回押してダウンロードを繰り返すことと、リクエストを複数回送ることは同じことではないのでしょうか? IEの同時最大接続数なども考え、レジストリを設定して試してみたのですが、動作は変わりませんでした。 ネット上でiframeを指定しての複数ダウンロードがMSのセキュリティ対策によりできなくなったとあったのですが、それを考慮しても、IEでの同時最大接続数が6であれば、6ファイルは同時にダウンロードできるのではないかと思って実装したのですが、成果を挙げることができませんでした。 実行できない理由など、お心当たりがありましたら、ご教授いただけますでしょうか。 繰り返しとなり申し訳ありません。 以上、宜しくお願い致します。
kurage

2015/07/14 11:29 編集

コメントを移動しました。
guest

0

ベストアンサー

こんにちわ。
申し訳ありませんが、コメントではコードハイライトが使えないので、また別で起こしました。
ChromeとIEで挙動が違うとのことでしたので少し調べました。

レスポンスのContentTypeHeaderにセットする内容で、挙動が変わるようです。
都合のよいものは見つけられませんでした。

このアプローチの仕方では、User-AgentContentTypeHeaderにセットするものを切り替えるといった方法でしか対応が不可能かもしれません。
eripongさんからご提示頂いている方法もご検討ください。
以上、よろしくお願いいたします。

lang

1<!DOCTYPE html> 2<html> 3<head> 4 <meta charset="UTF-8"> 5</head> 6<body> 7 <button id="btn">クリック!</button> 8 <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script> 9 <script> 10 $(function(){ 11 $('#btn').click(function(){ 12 for (var i=0; i<3; i++) { 13 var ifrm = '<iframe style="display:none" src="http://localhost:8080/test/Download" />'; 14 $(ifrm).appendTo('body'); 15 } 16 }); 17 }); 18 </script> 19</body> 20</html>

lang

1package test; 2 3import java.io.FileInputStream; 4import java.io.IOException; 5import java.io.InputStream; 6 7import javax.servlet.ServletException; 8import javax.servlet.http.HttpServlet; 9import javax.servlet.http.HttpServletRequest; 10import javax.servlet.http.HttpServletResponse; 11 12import org.apache.commons.io.IOUtils; 13 14public class DownloadServlet extends HttpServlet { 15 16 @Override 17 protected void doGet(HttpServletRequest req, HttpServletResponse resp) 18 throws ServletException, IOException { 19 20 InputStream inStream = new FileInputStream("c:\\test.txt"); 21 IOUtils.copy(inStream, resp.getOutputStream()); 22 23 // Chrome:3回DL IE:1回DL 24// resp.setContentType("text/plain"); 25// resp.setHeader("Content-Disposition", "attachment; filename=\"test.txt" + "\""); 26 27 // Chrome:3回DL IE:1回DL 28// resp.setContentType("application/pdf"); 29// resp.setHeader("Content-Disposition", "attachment; filename=\"test.txt" + "\""); 30 31 // Chrome:無反応 IE:無反応 32// resp.setContentType("text/plain"); 33// resp.setHeader("Content-Disposition", "filename=\"test.txt" + "\""); 34 35 // Chrome:無反応、IE:3回DL 36// resp.setContentType("application/pdf"); 37// resp.setHeader("Content-Disposition", "filename=\"test.txt" + "\""); 38 39 System.out.println("動いた"); 40 } 41}

投稿2015/07/15 00:43

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kurage

2015/07/15 21:45

おはようございます。 記載していただいた方法で実現することができました。 attachment部分を消してもよいのだとは知らず、また、ヘッダー部によって各ブラウザの挙動が異なる点についても気がつきませんでした。 記載していただいた方法でIE8 ,IE9で動作確認を行ったのですが、どちらも確認がとれました。 解決までお付き合いくださいまして、本当にありがとうございました。
guest

0

間違ってコメントの内容を投稿してしまいました。
ちょっと調べたので別の回答で上書きしておきます。

ここを見ると、
IEでも複数ファイルダウンロードできた、とあります。
これは使えないでしょうか?

投稿2015/07/14 14:58

編集2015/07/14 15:06
eripong

総合スコア1546

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kurage

2015/07/14 22:41 編集

調べていただきまして、ありがとうございます。 提示していただいたページを参考に実施してみたのですが、対象がzipである場合はIE、chromeの両方でダウンロードができたのですが、対象がテキストである場合、両方のブラウザでダウンロードが実施されませんでした。 拡張子によって挙動が異なるようです。 対象がzipである場合、この方法でならweblogic+IEでもダウンロードできるというのは、ご提示いただいたサイトにあるようにContent-Dispositionを指定するからということなのでしょうか。 この事象は、個々でダウンロードを行った場合と何が違うのでしょう?IEでファイルを一つずつダウンロードする場合は通知バーはきちんと個別に表示されると思うのですが...... 以上、宜しくお願い致します。
guest

0

こんにちは。
試しに作った複数ファイルをダウンロードさせるだけのサンプルソースを添付しますので、
レスする形ではなく新たに起こしました。
同じファイルのままですが、複数ファイルのダウンロードができました。

iframeをファイル毎に別に用意してやらないと、ファイル数分のダウンロードリクエストが飛ばないようです。この辺が動かない理由ではないでしょうか。

lang

1<!DOCTYPE html> 2<html> 3<head> 4 <meta charset="UTF-8"> 5</head> 6<body> 7 <button id="btn">クリック!</button> 8 <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script> 9 <script> 10 $(function(){ 11 $('#btn').click(function(){ 12 for (var i=0; i<3; i++) { 13 var ifrm = '<iframe id="ifrm" style="display:none" src="http://localhost:8080/schedule/Download" />'; 14 $(ifrm).appendTo('body'); 15 } 16 }); 17 }); 18 </script> 19</body> 20</html>

ご参考になればと思います。
以上、よろしくお願いいたします。

投稿2015/07/14 00:35

編集2015/07/14 00:37
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kurage

2015/07/14 11:28

こんばんは。 サンプルをご提示頂きましてありがとうございます。 ご提示頂いたソースを使わせて頂いて確認したのですが、サーブレットは動いて正常に処理を行うのですが、やはり1回しかダウンロードができませんでした。 それぞれのリクエストのセッションIDが同じであるのですが、そういった部分に原因が在るのでしょうか。 サーバー(weblogic)が対応していないなども考えられるのでしょうか。 繰り返しアドバイス頂いているのに成果を出せず申し訳ありません。 以上、宜しくお願い致します。
退会済みユーザー

退会済みユーザー

2015/07/14 12:04

こんばんわ。 まず、上記ロジックを試した環境は、Tomcatになります。 同一ブラウザからのリクエストですので、セッションIDが同じになるのは普通のことであり問題はないと思います。 WebLogicについては分かりかねます。 困りましたね・・・。 サーブレットは正常に動いているとのことですので、Chromeの Developer Tools等でレスポンスが返ってくるか、こないか、またHTTPステータスコード等調べることはできませんでしょうか?
eripong

2015/07/14 12:34

横から失礼します。 unishakooooさんが動作確認したのは、IE9でしょうか? また、kurageさんに現状でのサーバ側、クライアント側の ソースを可能な範囲で示してもらった方が良いのではないでしょうか?
退会済みユーザー

退会済みユーザー

2015/07/14 12:37

eripongさん、こんばんわ。 私が試したブラウザはChromeの最新版になります。
eripong

2015/07/14 12:44

なるほど。 kkurageさんはIE9なので、合わせられれば、 その方が良いですが、可能ですか?
退会済みユーザー

退会済みユーザー

2015/07/14 12:53 編集

申し訳ありませんが、IE9で試すのはきびしい状況です。 IE11でIE9エミュレーションモードでの確認をする程度なら可能ですが・・・。
kurage

2015/07/14 14:45

こんばんは。 eripong様、unishakoooo様、ご意見いただきましてありがとうございます。 現在のソースは下記となっています。 【画面1】 <script> $(function(){ $('#bttn').click(function(){ for (var i=0; i<3; i++) { var ifrm = '<iframe id="ifrm" style="display:none" src="ダウンロード用jsp?FILE=ファイル名" />'; $(ifrm).appendTo('body'); } }); }); </script> <body> ..... <button type="button" id="bttn">botton</button> ..... </body> 【ダウンロード用jsp】 <% String fileName = (String)request.getParameter("FILE"); %> <% if (fileName != null && fileName != "") { %> <script language="Javascript"> function doDownload() { document.form.action="ダウンロード用アクション"; document.form.submit(); } </script> <% } else { %> <script language="Javascript"> function doDownload() { } window.close(); </script> <% } %> <body onload="doDownload()"> </body> ダウンロード用のJavaメソッドでは、OutPutStreamにファイルデータを設定し、write()を実行しています。 上記を用いて処理を実行した場合、forループでまわした件数分、Httpステータスは200で返却されていることをアクセスログから確認しています。 また、weblogic+IE11でも同様にダウンロードができないことを確認しています。 同じソースで、weblogic+chromeでは複数ダウンロードは正常に行えました。 weblogic+IEの組み合わせが駄目だということなのでしょうか。 以上、宜しくお願い致します。
eripong

2015/07/14 14:58

unishakooooさん、了解です。 たまたま一緒でないと、環境を合わせるのは難しいですよね。 kurageさん、ソースコード投稿ありがとうございます。 同じソースでchromeで実行できるなら、組み合わせというより IEの問題と考えて良いと思います。
eripong

2015/07/14 14:59

間違って回答にコメントしてしまったのでそちらは無視してください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問