- PR -

サーブレットで画像を配信(?)したい

投稿者投稿内容
c9katayama
常連さん
会議室デビュー日: 2003/02/04
投稿数: 38
投稿日時: 2005-05-25 20:48
私は、いつもこれですね。
<img src="/servlet/画像用サーブレット">
他人が画像もって行ったり、バッチで消したり、
なんて面倒なことを考える必要ないですし。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2005-05-26 12:12
>c95029さん

私も同じですね。
<img src="/servlet/ImageServlet?img=hoge">
みたいな感じでやっています。

画像に限らず「ファイル」をユーザにダウンロードさせる場合、
<a href="/servlet/DownloadServlet?file=hoge">hoge.xls</a>
のように、リクエストを受けてからファイルイメージを作成して、
ファイル化するのではなく、サーブレットのストリームで返すようにしています。
ぽち
常連さん
会議室デビュー日: 2005/05/24
投稿数: 25
投稿日時: 2005-05-31 10:52
okutinさん、MARUさん、c95029さん、かつのりさん、レスありがとうございます。
#ネットにアクセスできない環境だったので、返事遅れました。

> <img src="/servlet/画像用サーブレット">
> 他人が画像もって行ったり、バッチで消したり、
> なんて面倒なことを考える必要ないですし。
面倒なこと考える必要ないのはいいですね。
しかし画像用サーブレットで具体的に何をしたら良いのかどうもイメージできません。
かつのりさんが書いている、「ファイル化するのではなく、サーブレットのストリームで返す」ということでしょうか?
またストリームで返すとは、どうやったらいいのでしょう?

現状では、MARUさんの方法(セッション管理)でテストしていました。
セッションの開始時間をIDとして、専用のフォルダを作成することはできました。
しかし、セッションが切れたことを検出する方法がわかりません。
(HttpSessionListenerをどうやって使うの? 私には常駐ソフトが必要な気が
してならない、他の方法が考えられない。)

以上2つの実現方法について、更なるアドバイスお願いいたします。




MARU
常連さん
会議室デビュー日: 2005/02/16
投稿数: 35
投稿日時: 2005-05-31 11:20
HttpSessionListenerに関しては私が解説するより以下のサイトを見た方が良いと思います。

Javaの道様
Servlet(リスナー(HttpSession))

要はHttpSessionListenerを継承したクラスを用意し、
public void sessionDestroyed(HttpSessionEvent e) を実装する。
そのクラスをweb.xmlに登録する。
するとセッションが切れたときに、自分が実装したsessionDestroyed()が呼ばれます。

HttpSessionEventクラスからセッションID等もとれますので、
削除の実装そのものは難しくないと思います。
ぽち
常連さん
会議室デビュー日: 2005/05/24
投稿数: 25
投稿日時: 2005-05-31 15:37
MARUさん、レスありがとうございます。

教えていただいたサイトを見ながら、下記のようなクラスを作成し、web.xmlに登録しました。(web.xmlは、既にあったものに追記してみた)
しかし、ディレクトリが削除されませんでした。
sessionDestroyed()が呼ばれたのかを確認するために、適当なディレクトリの作成をしていますが、これも作成されませんでした。
(ということは、呼ばれていない?)
デバッグ方法について、検索してみましたが適切なものが見つからず困っています。
この場合、どのようにしてデバッグしたらよいでしょうか?
また、下記のソース等で不具合箇所がありましたらご指摘願います。

-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class checkSessionServlet extends HttpServlet implements HttpSessionListener
{
public void sessionCreated(HttpSessionEvent hse)
{
}

public void sessionDestroyed(HttpSessionEvent hse)
{
// 呼ばれたか確認のためにディレクトリを作ってみる
File filePathDbg = new File("C:\\123\\");
if( filePathDbg.mkdirs() )
{
}

HttpSession hs = hse.getSession();
Long lId = (Long)hs.getAttribute("id");
if(lId==null)
{
// エラー
}
else
{
// サブディレクトリの削除
String strPathName = getServletContext().getRealPath("/");
String strPath = strPathName + "images\\MapImage\\" + String.valueOf(lId) + "\\";
File filePath = new File(strPath);
if( filePath.delete() )
{
// ディレクトリ削除成功
}
else
{
// ディレクトリ削除失敗
}
}
}
}

-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
※デフォルトでインストールされたweb.xmlの<listener>の最後に追加した。
   <listener>
     <listener-class>checkSessionServlet</listener-class>
   </listener>

MARU
常連さん
会議室デビュー日: 2005/02/16
投稿数: 35
投稿日時: 2005-05-31 16:59
[呼ばれてない?理由]
設定が間違ってなければ、セッション廃棄の時に呼び出されてるはずです。
Tomcatのタイムアウトはデフォルトで30分なので、
30分すぎないとセッション切れは呼ばれません。
もしかしたらそれを待たずに呼ばれない?と勘違いしてると思われます。

とは言っても毎回テスト時に30分待っていては時間がもったいないので、
タイムアウト値を短く設定してする等してテストしてみてください。

タイムアウト値はweb.xmlの
<session-config>内の<session-timeout>の値(単位は分だったかな?)
を変更すれば設定できるはずです。

[フォルダが削除されない理由]
フォルダが削除されないのはjava.io.File#delete()の仕様です。
>そのディレクトリが削除されるためには空である必要があります。
と書いてあります。つまり一端中身を全部削除しないと駄目ということです。
java.io.File#delete()

自分はこんな感じのメソッドを用意して使い回してます。
コード:

/**
* フォルダを削除する。
* @param folder File
*/
public void deleteFolder( File folder ){
//フォルダが存在する時
if( folder.exists() ){
//そのフォルダ内のファイル、フォルダ一覧を取得する。
File[] chlidFile = folder.listFiles();
//取得に成功した時
if (chlidFile != null) {
int size = chlidFile.length;
// フォルダ内のファイル、フォルダを全部削除する。
for (int i = 0; i < size; i++) {
//そのファイルがフォルダだった場合
if (chlidFile[i].isDirectory()) {
//フォルダを削除する。
deleteFolder( chlidFile[i] );
}
else {
//ファイルを削除する。
chlidFile[i].delete();
}
}
}
//フォルダを削除する。
folder.delete();
}
}



あまり綺麗なコードではないですが、ご参考までに。



[ メッセージ編集済み 編集者: MARU 編集日時 2005-05-31 17:01 ]
ぽち
常連さん
会議室デビュー日: 2005/05/24
投稿数: 25
投稿日時: 2005-05-31 19:19
MARUさん、レスありがとうございます。

>Tomcatのタイムアウトはデフォルトで30分なので、
>30分すぎないとセッション切れは呼ばれません。
>もしかしたらそれを待たずに呼ばれない?と勘違いしてると思われます。
投稿直後にエクスプローラで見たら、ディレクトリが作成されていました。

>フォルダが削除されないのはjava.io.File#delete()の仕様です。
>そのディレクトリが削除されるためには空である必要があります。
そうだったんですか。
で現在テスト的に、ディレクトリ削除されないのを承知で
以下のようにIDを取得できたか否かを確認するためのディレクトリ
作成を入れてみました。
すると、どちらのディレクトリも作成されませんでした。
IDの取得方法、判定などに問題があるのでしょうか?

HttpSession hs = hse.getSession();
Long lId = (Long)hs.getAttribute("id");
if(lId==null)
{
// 呼ばれたか確認のためにディレクトリを作ってみる
File filePathDbg = new File("C:\\123\\");
if( filePathDbg.mkdirs() )
{
}
}
else
{
// 呼ばれたか確認のためにディレクトリを作ってみる
File filePathDbg = new File("C:\\456\\");
if( filePathDbg.mkdirs() )
{
}
// 以降のディレクトリ削除処理はそのまま
}



ぽち
常連さん
会議室デビュー日: 2005/05/24
投稿数: 25
投稿日時: 2005-05-31 20:02
状況の追記です。

Long lId = (Long)hs.getAttribute("id");
で、IllegalStateExceptionが発生していました。
この場合、どうやってidを取得すればよいのでしょうか?

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