Search code examples
struts2annotationsstruts2-convention-plugin

Can't call action using annotation in Struts 2


Here is my action class:

FirstAction.java:

 @Namespace(value = "/User")
 public class FirstAction extends ActionSupport {

/**
 * 
 */
private static final long serialVersionUID = 1L;

@Action(value = "run4", results = { @Result(name = "task1", location = "task1.jsp") })
private String task1() {
    return "task1";
}

@Action(value = "run5", results = { @Result(name = "task2", location = "task2.jsp") })
private String task2() {
    return "task2";
}

@Action(value = "run6", results = { @Result(name = "task3", location = "task3.jsp") })
private String task3() {
    return "task3";
}
}

SecondAction.java:

 @Namespace(value = "/Admin")
public class SecondAction extends ActionSupport {

/**
 * 
 */
private static final long serialVersionUID = 1L;

@Action(value = "run1", results = { @Result(name = "task1", location = "task1.jsp") })
private String task1() {
    return "task1";
}

@Action(value = "run2", results = { @Result(name = "task2", location = "task2.jsp") })
private String task2() {
    return "task2";
}

@Action(value = "run3", results = { @Result(name = "task3", location = "task3.jsp") })
private String task3() {
    return "task3";
}
}

struts.xml:

 <struts>
    <constant name="struts.action.extension" value="html" />
    <package name="default" extends="struts-default"></package>
</struts>

web.xml:

<welcome-file-list>
   <welcome-file>redirect.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>struts2</filter-name>
<filter-class>
    org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
<init-param>
    <param-name>actionPackages</param-name>
    <param-value>com.sem4.actions</param-value>
</init-param>
</filter>
<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Session Config -->
<session-config>
    <session-timeout>30</session-timeout>
</session-config>

This is redirect.jsp:

 <div>
      <a href='<s:url action="run1" namespace="Admin"></s:url>'>Action run1, namespace Admin</a>
        <br> 
        <a href='<s:url action="run2" namespace="Admin"></s:url>'>Action run2, namespace Admin</a> 
        <br> 
        <a href='<s:url action="run3" namespace="Admin"></s:url>'>Action run3, namespace Admin</a>
 </div>
 <div>
      <a href='<s:url action="run4" namespace="User"></s:url>'>Action run1, namespace User</a> 
        <br> 
        <a href='<s:url action="run5" namespace="User"></s:url>'>Action run2, namespace User</a>
        <br> 
         <a href='<s:url action="run6" namespace="User"></s:url>'>Action run3, namespace User</a>
 </div>

And my library:

  antlr-2.7.6.jar
  commons-collections-3.1.jar
  commons-fileupload-1.2.1.jar
  commons-io-1.3.2.jar
  commons-lang-2.3.jar
  commons-logging-1.1.jar
  dom4j-1.6.1.jar
  ejb3-persistence.jar
  freemarker-2.3.13.jar
  hibernate-annotations.jar
  hibernate-commons-annotations.jar
  hibernate-validator.jar
  hibernate3.jar
  hsqldb.jar
  javassist-3.9.0.GA.jar
  jta-1.1.jar
  junit-3.8.1.jar
  log4j-1.2.15.jar
  mysql-connector-java-5.0.7-bin.jar
  ognl-2.6.11.jar
  slf4j-api-1.5.8.jar
  slf4j-log4j12-1.5.8.jar
  struts2-convention-plugin-2.1.6.jar
  struts2-core-2.1.6.jar
  struts2-fullhibernatecore-plugin-1.4-GA.jar
  xwork-2.1.2.jar

When I click a link in redirect.jsp to call an action, ex: call action run4 in namespace "User", it's throwing

  HTTP Status 404 - There is no Action mapped for namespace /User and action name run4

I'm trying to find what makes this wrong, but it looks like my code is fine.


Solution

  • The action method should be public. Struts2 not allows to map an action on private methods, e.g.

    @Action(value = "run4", results = { @Result(name = "task1", location = "task1.jsp") })
    public String task1() {
        return "task1";
    }
    

    Also it's not necessary to write annotations to configure actions via convention plugin. It has already created a configuration that can be used by convention. You can see the docs page to get how to use this configuration.