- PR -

StrutsのActionクラスについて質問

1
投稿者投稿内容
POTETO
常連さん
会議室デビュー日: 2003/10/06
投稿数: 41
投稿日時: 2003-12-07 05:02
こんにちは、ぴーたんです。
最近Strutsの勉強をはじめたのですが、Actionクラスについて質問です。
Actionクラスを継承した以下のようなクラスを作成して、
実際の処理はこのクラスを継承したクラス内に記述したいと思うのですが、
スレッドセーフ(?)な作りになっているでしょうか?
本などに紹介されている例などでは、Actionクラスが呼び出される度に
newされているかどうか書いてありません。インスタンスが再利用されていると
インスタンス変数にコネクションなど持つのは危険でしょうが。

public class ZZZAction extends Action {
private Connection conn = null;
public ZZZAction() {
super();
}
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response
)throws Exception {
conn = <コネクション取得処理>;
  try {
String zzz = doAction();
return mapping.findfoward(zzz);
}catch(Exception e){
ロールバック処理
}finally{
コネクションクローズ処理
}
}
abstract String doAction();
}

コネクションの取得やクローズ、Log4JのLogger取得などを各Actionクラスに
記述するのが面倒なのでそれを親クラスに記述したいと考えています。
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2003-12-07 13:21
コンストラクタでログを出力するなどすればわかりますが、Actionクラスのインスタンスは1つだけ生成されて複数のスレッドから使いまわされます。

例示していらっしゃるコードは、Action のインスタンスを毎回生成するかどうかに関わらずスレッドセーフになっていると思います。

あくまで例だと思うので、突っ込む意味があるかわかりませんが catch(Exception e) という記述をするとどんな例外を吐くメソッドを呼び出してもコンパイラが指摘してくれないので危険です。丁寧に必要な例外だけを catch するように書くと良いですね。
未記入
会議室デビュー日: 2003/02/21
投稿数: 10
投稿日時: 2003-12-07 14:03
引用:

インギさんの書き込み (2003-12-07 13:21) より:
例示していらっしゃるコードは、Action のインスタンスを毎回生成するかどうかに関わらずスレッドセーフになっていると思います。



いや、スレッドセーフになってないですよ。「conn」が。

引用:

あくまで例だと思うので、突っ込む意味があるかわかりませんが catch(Exception e) という記述をするとどんな例外を吐くメソッドを呼び出してもコンパイラが指摘してくれないので危険です。丁寧に必要な例外だけを catch するように書くと良いですね。


確かに一般的には「catch(Exception e)」はだめだと言われていますが、
ぴーたんさんはおそらく、例外が発生した場合、それがどんな例外でもロールバックしたかったのでしょう。
その場合、必要な例外のみ書くと漏れることがありますよね?
特にRuntimeExceptionなんて何が投げられるかわかったもんじゃないですし。
この場合は「catch(Excption e)」または「catch(Throwable e)」でキャッチする方が良いと思います。
「String doAction() throws Exception」となっていればインギさんの指摘通りなのですが。
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2003-12-08 00:42
>いや、スレッドセーフになってないですよ。「conn」が。
おっと、肝心なところを見逃していました。スコープをメソッド内にしないとだめですね
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2003-12-08 00:44
>いや、スレッドセーフになってないですよ。「conn」が。
おっと、肝心なところを見逃していました。スコープをメソッド内にしないとだめですね
あと、Statement/PreparedStatement/ResultSet もちゃんとクローズしましょう。コネクションプールを利用していると問題になることがありますので。
POTETO
常連さん
会議室デビュー日: 2003/10/06
投稿数: 41
投稿日時: 2003-12-08 02:37
こんばんわ、ぴーたんです。
インギさん、しゅうさん、返信ありがとう御座います。
やはり、Actionクラスはインスタンスが使いまわされますか。
コネクションをメソッド内で生成して、引数で渡せす方法にします。
引数用のbeanを使って渡そうか。。。

だいたい、Actionクラスの使い方として、親クラスを作るのは
スタンダードではないのでしょうか?
経験豊富な皆様、ご教授願います。
でくのぼう
大ベテラン
会議室デビュー日: 2003/10/06
投稿数: 162
投稿日時: 2003-12-08 13:07
引用:

だいたい、Actionクラスの使い方として、親クラスを作るのは
スタンダードではないのでしょうか?



あまりにも冗長になるならそうした実装でも問題無いと思いますよ。
でも中には Action を継承する以外の解決策もあるでしょうし・・・。

ユーティリティメソッドを集めたクラスを作っても解決できたり
モノによっては RequestProcessor を拡張する方が自然な場合がありますし
Struts に依存せず Filter を使ったり。

やはり一概には言えませんね。
1

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