0

My idea is to perform actions using Struts2 the below way using a single Action class and multiple methods in it:

View roles action: manage/roles.action?method%3Aview=View Add role action: manage/roles.action?method%3Aadd=Add

The URLs are called through invoking submit buttons as shown below from test.jsp:

<s:form namespace="/manage/" action="roles" method="get" >
    <s:submit method="view" value="View" />
    <s:submit method="add" value="Add" />
    <s:submit method="edit" value="Edit" />
    <s:submit method="delete" value="Delete" />
</s:form>

In struts.xml, I configured:

 <package name="portal" namespace="/manage/" extends="struts-default">
    <action name="home">
        <result>/WEB-INF/jsp/manage/roles/test.jsp</result>
    </action>

    <action name="roles" class="struts2.actions.RoleAction" method="view">
        <result name="success">/WEB-INF/jsp/manage/roles/viewRoles.jsp</result>
    </action>

    <action name="roles" class="struts2.actions.RoleAction" method="add">
        <result name="input">/WEB-INF/jsp/manage/roles/addRole.jsp</result>
        <result name="success">/WEB-INF/jsp/manage/roles/viewRoles.jsp</result>
    </action>

Unfortunately, when I'm pressing View button, it's showing the result JSP of "add" method. Why?

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
Faisal
  • 645
  • 3
  • 11
  • 24

1 Answers1

0

Because you have two actions with the same name, roles.

How would you differentiate between... /roles and /roles?

They should have different names–different URLs. Since they're the same URL the last one configured will win; you're overwriting your own definitions. How about giving them different names, like /addrole and /viewrole, or namespacing them, like /roles/add and /roles/view, etc.?

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
  • Yes, I noticed that the last configured action is being executed. In Struts 1, I used something like `/roles?action=add`, `/roles?action=view` etc. I'm trying the same in Struts 2 as well - which seems not possible. The idea is simple - one action class catering to different possible methods of action (`/roles.action?method=add`, `/roles.action?method=view` etc.) where each such method has its own input and own result. No common input and result. How to realize this? – Faisal Jul 17 '14 at 10:19
  • @Faisal It *is* possible, using dynamic method invocation (disabled by default somewhere around S2.1 IIRC). I'm not a fan, and I'd border on saying it's an S2 antipattern. There's just no real need for it. – Dave Newton Jul 17 '14 at 11:49
  • I just read about DMI here: http://struts.apache.org/release/2.3.x/docs/action-configuration.html#ActionConfiguration-DynamicMethodInvocation Could you please provide me a good example of DMI? Not wildcard. – Faisal Jul 17 '14 at 12:40
  • @Faisal An example of what? As the docs state: Dynamic Method Invocation (DMI) will use the string following a "!" character in an action name as the name of a method to invoke (instead of execute). A reference to "Category!create.action", says to use the "Category" action mapping, but call the create method instead. – Dave Newton Jul 17 '14 at 12:45
  • Ok, well I meant an example implementation of DMI. However, the official URL discussed above helped me and I realized my idea (all these are working now `/roles!view.action`, `/roles?method:view`, `/roles?method%3Aview`). Though I have a question - method:view is being encoded as method%3Aview. How to disable this and use method:view instead? – Faisal Jul 17 '14 at 13:32