[CUBBY-74] 1フォームで複数アクションメソッドへの対応 Created: 2008-01-20  Updated: 2009-07-05  Resolved: 2008-05-19

Status: Closed
Project: Cubby
Component/s: Core
Affects Version/s: 1.0.0-RC1
Fix Version/s: 1.1.0-rc1

Type: New Feature Priority: Major
Reporter: jfut Assignee: baba
Resolution: Fixed Votes: 0
Labels: None


 Description   

1フォームで複数アクションメソッドへの対応が出来ると良いと思います。

具体的には、ExamplesのTODOアプリでconfirm.jspの戻るに対応するアクションメソッドはTodoAction#confirm_backだと思いますが、現在これを呼び出す手段がないようです。
そこで、PathResolverImpl#findForwardInfoかどこかを修正して、

<t:form action="${contextPath}/todo/save" method="post" value="${action}">
<input type="submit" name="confirm_back" value="戻る"/>
<input type="submit" value="登録"/>
</t:form>

とあった時に、「戻る」ボタンでsubmitした場合は、実行するアクションメソッドをTodoAction#saveではなく、TodoAction#confirm_backに出来ると良いと思います。ただ、actionで指定しているsave部分を無視することになりますので仕様としてもっと他に良いものがあるかもしれません。

SAStrutsとS2Strutsでも似たようなものがあり、SAStrutsですとS2ActionMapping#findExecuteConfigでアクションクラスの関数名がリクエストパラメータにあれば、そのアクションメソッドを実行するようです。<input>タグの「nameとvalue」はリクエストパラメータに「キーと値」として入るので、この方法で期待する動作になるようです。



 Comments   
Comment by baba [ 2008-05-19 ]

対応してサンプル追加しました。

Comment by agata [ 2008-02-02 ]

>@OnSumitに別けても別けなくてもあんまり変わらないので実装しやすい方で良いと思います。

どちらでもOKだと思います。
利用者が驚きが少なく、わかりやすいほうで。

@Acceptもパスが同じでGETやPOSTの違いで実行するメソッドを切り替える仕様なので、
同じように別アノテーションのほうがわかりやすいかなー

Comment by jfut [ 2008-02-02 ]

URIにマッピングされてしまうのが好ましくないということですね。理解しました。

@Pathはそのままで、アノテーションでボタンの名前を指定するのはどうでしょう?

public ActionResult save() {

@Path("save")
@OnSubmit("confirm_back")
public ActionResult back() {

この指定方法、良いと思います。

もし@Pathだけで実装するとしたら、@Path("save")のようにsubmitを省略した場合は、name未指定や他のsubmitで指定されてないものを処理するなどにすれば良いのかなと思います。submitがあってvalue()がないのは例外で。

@Path("save") もしくは @Path未指定、URIにマッピングされる
public ActionResult save() {

@Path("save", submit="confirm_back")、URIにマッピングされない
public ActionResult back() {

@OnSumitに別けても別けなくてもあんまり変わらないので実装しやすい方で良いと思います。

Comment by Anonymous [ 2008-02-02 ]

@Pathのvalue()だけだと、URIが

${contextPath}/todo?confirm_back=戻る

${contextPath}/todo/confirm_back

のどちらでもアクセスできるようになると思います。
これは好ましくないかな、と。

@Pathにsubmit属性をつけると、

@Path("save",submit="save")
public ActionResult save() {

ここが冗長になってしまいますね。

@Pathはそのままで、アノテーションでボタンの名前を指定するのはどうでしょう?
/todo/save にアクセスして、ボタンのnameがしていされていなかったら#save()、nameが"confirm_back"だったら#back()
で、どうですか?

public ActionResult save() {

@Path("save")
@OnSubmit("confirm_back")
public ActionResult back() {
Comment by agata [ 2008-02-02 ]

@Pathだけで処理するなら以下のような方法もありますね。

@Path("save",submit="save")
public ActionResult save() {

@Path("save", submit="confirm_back")
public ActionResult back() {

Comment by jfut [ 2008-02-02 ]

actionの指定が"${contextPath}/todo/"で対応するアクションクラスを特定できるようでしたら、
新しく@OnSubmitを足さなくても@Pathの値でアクションメソッドを特定しても良いような気もします。
(Cubbyのアクションクラス・メソッド特定の仕様の理解が足りないだけかもしれません。。)

Comment by agata [ 2008-02-02 ]

シンプルでいいんじゃないかなーと思いました。+1

URIテンプレートの機能は、クラスまでのパスで表現してもらう形になりますよね。

Comment by baba [ 2008-02-01 ]

なんとなく仕様を考えてみました。
ご意見ください。

  • @OnSubmitがついたメソッドはクラスまでのパスでURIにマッピングされ、URIには直接マッピングされない
  • @OnSubmitがついたメソッドは、URI埋め込みパラメータの数が同じならばURIにマッピングされたメソッドよりも優先度をあげる
  • 同じメソッドに@Pathと@OnSubmitが両方あったら例外をだす
  • 対象のメソッドがないとき、エラーは404 NotFoundでいいのか?
    <t:form action="${contextPath}/todo/" method="post" value="${action}">
    (1) <input type="submit" name="save" value="登録"/>
    (2) <input type="submit" name="confirm_back" value="戻る"/>
    (3) <input type="submit" name="none" value="対応メソッドなし"/>
    (4) <input type="submit" value="name未指定"/>
    </t:form>
    
    public FooAction extends Action {
    
    	// (1)に対応
    	@OnSubmit
    	public ActionResult save() {
    
    	// (2)に対応
    	@OnSubmit("confirm_back")
    	public ActionResult back() {
    
    	// (3)、(4)はnone()というメソッドも@OnSubmit("none")が指定されたメソッドもないので、
    	// /todo/にマッピングされたメソッドをへのアクセスになる
    	// ここでは#index()メソッドがあるのでこれが動く
    	public ActionResult index() {
    
    	// このメソッドは /foo/bar でアクセスできる
    	public ActionResult bar() {
    
    }
    

    どう実装するかは全然考えてません・・・

Generated at Tue Apr 16 13:02:37 JST 2024 using Jira 9.15.0#9150000-sha1:9ead8528714127d8cfabf2446010d7e62c0a195c.