yohjizzz's Blog

I'm a Programmer.

リクエストパラメータで Action のプロパティを更新できる/できないの件

ひがさん、お忙しいところいつもコメントありがとうございます。
できれば今回もお付き合い頂けると非常にありがたいッス○

今のSAStrutsのアクションは、外部バインディングしない設定になっているので、
リクエストパラメータの値でアクションのプロパティは更新できませんよ。

Action と ActionForm - ようじのにっき

ひがさんの言っている「外部バインディング」は以下に合致しないのかもしれないけど。


S2RequestProcessor#processPopulate(..) のこの箇所↓↓

setProperty(actionMapping.getActionForm(), name, params.get(name));

ここでHTTPパラメータ(GETだろうがPOSTだろうが)を
actionMapping(実態は S2ActionMapping)の getActionForm() の戻り値に対してセットしてますよね??
DIコンテナによるバインドではなくて純粋に Struts(プロセッサ)の仕様として)

S2ActionMapping#getActionForm() は、、
ActionCustomizer によってあらかじめ Action のフィールドに @ActionForm の有無をチェックされており、
・@ActionForm が1つ以上定義されていればそのフィールド(*Form)のコンポーネント
・@ActionForm が1つ以上定義されていなければ Action 自身のコンポーネントを返します。


よって @ActionForm がなければ、
HTTPパラメータ(リクエストパラメータ)は Action のプロパティ(合致する名称があれば)を更新します。


ここまでで勘違いがあるのか・・・!?>id:higayasuo さん、できればコメント下さい。(_ _)


public class ItemAction {

    public String itemNo;

    public ItemDto itemDto;

    @Execute(validator = false, urlPattern = "detail/{itemNo}")
    public String detail() {
        this.itemDto = this.itemService.findByItemNo(this.itemNo);
        return "detail.jsp";
    }

}

こいつ↑は「~/item/detail/888-88888/」というURLで、
商品番号 "888-88888" に該当する商品情報を itemDto に詰めます。(画面に表示します。)

でも次のURLでも同じことが行えますよね⇒「~/item.do?SAStruts.method=detail&itemNo=888-88888」


ここでちょっと悪ふざけをします。
次のURLでは itemDto には String は詰められねー!と怒られます。⇒「~/item.do?SAStruts.method=detail&itemDto=hoge」

なので1つしかないけど itemNo を ItemForm に定義して Action を以下のようにします。

    @ActionForm
    @Resource
    protected ItemForm itemForm;

そうすると前述した仕様であればプロセッサはパラメータのバインド対象を ActionForm のみとしてくれるので、
悪ふざけしたURLでもシステムエラーにはならずに済みます。


ここらへんの話は⇒SAStrutsのアクションのpublicフィールドですね。


上記の例のようにHTTPパラメータを受け取って何かを表示する、というケースなら、
恐らく @ActionForm を定義しているのでプロセッサによって、
Action のプロパティ(publicフィールド)が更新されることはないでしょう。


でも前回のエントリーで言いたかったのは(長くなりましたがここからで…)、
HTTPパラメータを受け取ることなく(@ActionForm を定義する必要のない Action で)、
何かしらの動的な情報を表示する必要がある場合、
上記の Action と同じようにpublicフィールドに表示専用の DTO を定義したいのです。

が、、、そーすると悪ふざけのURL(xxxDto=hoge)によって、
S2RequestProcessor#processPopulate(..) 内で IllegalPropertyRuntimeException がスローされてしまいます。


そこで前回のエントリーのようなことを思った訳です。

これを防ぐには、、
 1)表示項目は public にはせず、public な getXxx() を用意する
 2)ダミーの @ActionForm を定義する

Action と ActionForm - ようじのにっき


長くなってしまった><