cafegale(LeafCage備忘録)

LeafCage備忘録(はてなダイアリー)と統一しました。

SAStrutsプロジェクトの作成

Doltengのアプリケーションタイプを「Webアプリケーション」、表示(プレゼンテーション)を「SAStruts」、永続化を「S2JDBC」、サーバ管理を「WTP(Servlet2.5)」にして作成。

チュートリアル(サンプル)を閲覧する

「Super Agile Strutsチュートリアル」のインストール - 愚鈍人
※クラスファイル右クリでの「SAStruts」→「サーバで表示」でEclipseが簡易ブラウザになる。

tomcatをただ起動していただけの今までのやり方と違って、専用のサーバを立てる

サーバービューを表示して「新規サーバウィザードから新規サーバを定義」から、{SAStrutsプロジェクト名}をウィンドウ左から右へ(「使用可能」から「構成済み」へ)移動。
そのサーバを起動。
(他のtomcatサーバが起動されているのなら、停止させておく。java.net.BindException: Address already in use:が出たとき、全てのtomcatを停止させてから再起動したらうまくいった)

Tomcatの自動リロードを無効にする(S2ConainerにHOT deploy機能がすでにあるから)

サーバービューのTomcatをダブルクリックすると設定を行うためのエディタが表示されるので、「モジュールタブ」を選ぶ

編集ボタンを押し、「自動最ロード使用可能」のチェックをはずす
で設定を保存

Actionの作成

フィールドActionFormはprotectedにしてアノテーション@Resourceと@Actionformを付ける。*1

Actionのpublicなフィールドやgetterは自動でHttpServletRequest#setAttribute()される…JSPに値を渡したいとき利用

  • @Resource
        • DIするコンポネントとして登録。同じ働きのものに@Bindingがある
        • まだ深く理解できていないので仮説。@Resourceを付けると実装が注入される。ということは、@Resourceを付けられる側は、インターフェイスや抽象クラスみたいなの?なのか?
        • いや、どうも、ただオブジェクトを代入してるだけっぽい。つまりObject object = new Object(); の右辺の操作。
        • とりあえず、@Resourceを付けたものにはまるものをどっかから探し出してきてはめるというのが基本(どこから探してくるのかはよくわからん)
  • @ActionForm
        • ActionFormをDIしてくる
  • @Execute
        • 実行メソッド。次に遷移するJSPパスか、別のアクションパス*2を返却。アクション名の後ろに?redirect=trueを付与するとフォワードではなくリダイレクト(PRGパターン*3 )
    • validator
        • 既定true
    • input
        • エラーの場合の遷移先jspを指定。validatorがtrueなら必須
    • validate
        • ActionMessagesを返す検証用メソッド名を指定。ActionMessagesが空でなければエラーが出たとし、input値のページに遷移
    • urlPattern
        • このActionが作るurlを、メソッド名でなく、指定した名前で作る。urlPattern="result/{id}"だと{}で囲った部分が評価され結果が代入される(Vimの{}付き関数名みたいなイメージ?)/「id」はアクションフォームのプロパティとする
    • removeActionForm
        • instance=InstanceType.SESSIONなアクションフォームを終了時に廃棄したいときtrueにする
    • redirect
        • trueにするとforwardではなくredirectで遷移
    • reset
        • ActionFormにあるresetメソッド名を指定。初期値"reset"


strutsのAction

public class example extends Action {
	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		MyForm myform = (MyForm) form;
		return mapping.findForward("forward");
	}
}

が、SAStruts

public class EchoAction {
	@Resource
	@ActionForm
	protected MyForm myform;

	@Execute(validator=false)
	public String example(){
		return "example.jsp";
	}
}

とほぼ等価

Action名はURLと密接

Super Agile Struts - Feature Reference
URLの作られ方
EchoActon.java→echo→echo/{メソッド名}/ ※ただしメソッドがindex()の場合はecho/がURL

ActionクラスにDIできるもの
public class SampleAction {

  @Resource
  protected UserDto userDto;  //DTO (HttpSessionを収めたBean的なもの)

  @Resource
  protected HttpSession session;
  @Resource
  protected HttpServletRequest request;
  @Resource
  protected ServletContext context;
  
  protected HttpServletResponse response = S2Container.getComponent(HttpServletResponse.class);
  HttpServletRequest request = RequestUtil.getRequest();
  ...
}
同期トークンを扱う

トークンをセットする

public class TokenAction{
@Resource
protected HttpServletRequest request;

@Execute(validator=false)
public String index(){
TokenProcessor.getInstance().saveToken(request); //トークンを取得しrequestに保存する
return "index.jsp";
}

検証を行うために@Executeのvalidate要素に検証用メソッド名を指定

@Execute(validator=false, validate="validate", input="index.jsp")
public ActionMessages validate(){
  ActionMessages errors = new ActionMessages();
  if(!TokenProcessor.getInstance().isTokenValid(request, true)){
    errors.add(ActionMessages.GLOBAL_MESSAGE,
      new ActionMessages("errors.invalid", "TOKEN"));
  }
  return errors;
}

TokenProcessorのisTokenValid({トークン保存先}, {検証後トークンを削除するか})
コンストラクタActionMessage({メッセージキー}, {メッセージ引数})

ActionFormの作成

アクセサ(ゲッタセッタ)は必要ない
入力チェックはアノテーション
メソッドに付ける

  • @Required
        • 入力必須にする Actionで@Execute(validator=true, input="backword.jsp")みたく設定の必要あり
    • target
        • ここで指定した実行メソッド名のときだけ検証を行う。複数指定はカンマ区切りで
  • @Maxlength(maxlength=20)
  • @IntegerType

クラスに付ける

  • @Component
    • instance
        • セッションに入れるならInstanceType.SESSIONを値に。また、セッションに格納されるクラスはjava.io.Serializableをインプリメントしなければいけない。

DTOの作成(HttpSession上で管理する必要のあるデータ)

  • @Component
    • instance
        • このセッションのライフサイクル (instance = InstanceType.SESSION)

DTOはセッションをまたぐ入れ物、Beanみたいなもの

*1:publicフィールドだと@Resourceを付けなくても自動バインディングの対象になる代わりに、自動で何かいろいろやられる

*2:単純に同じアクションクラスのメソッド名だったりする

*3:PostRedirectGetパターン。フォームの送信後に表示される画面でF5キーを押したとき二重にフォームが送信されるのを防ぐために使われる