Annotation base namespace mapping in Struts 2

Posted on August 09, 2014

The namespace provides a mapping from the URL to the package. Through namespace you can modularize your application. Most of the Struts developer get confused with the namespace and their mapping for the action and result path.

Here I am describing the annotation base configuration for namespace. Annotation base configuration is bit tricky and complicated but provides greater advantage over the XML based configuration.

It depends on the some points:

  1. Weather the Namespace is specified or not.
  2. Weather the ResultPath is specified or not.
  3. Weather Action annotation is specified at class level or method level.

Note: If Namespace is not specified then the action will consider in the default namespace and default namespace is denoted by ?/?.

Now, here is the rule for namespace and action mapping.

  1. If no ResultPath annotation is specified then result page will render from the specified path.
  2. If ResultPath is not specified then result will depends of the action annotation place and namespace. If action annotation is specified at class level then result will render from /WEB-INF/content and folder the matches to the namespace of the action. If action is defined at the method level then result will render from /WEB-INF/content itself.

If you find it complicated below is the more specific detail about these rules.

Case I: CaseFirstAction.java Namespace of the action is @Namespace (?/user?) Action specified at class level, @Action (value = ?/ casefirst?) ResultPath is not specified, Result will render from /WEB-INF/content/user folder.
package com.vivekpatidar.action;

import org.apache.struts2.convention.<wbr />annotation.Action;
import org.apache.struts2.convention.<wbr />annotation.Namespace;
import org.apache.struts2.convention.<wbr />annotation.Result;

/**
 * Action annotation is specified at class level and ResultPath annotation is
 * not specified. Result will serve from &quot;/WEB-INF/content/user/&<wbr />quot;.
 *
 * @author Vivek Patidar
 */

@Namespace("/user")
@Action(&quot;/casefirst&quot;<wbr />)
@Result(name = "success", location = "result.jsp")
public class CaseFirstAction {

    public String execute() {
        return "success";
    }

}
  Case II: CaseSecondAction.java Namespace of the action is @Namespace (?/user?) Action specified at method level, @Action (value = ?/ casesecond?) ResultPath is not specified, Result will render from /WEB-INF/content folder.
import org.apache.struts2.convention.<wbr />annotation.Action;
import org.apache.struts2.convention.<wbr />annotation.Namespace;
import org.apache.struts2.convention.<wbr />annotation.Result;

/**
* Action annotation is specified at method level and ResultPath annotation is
* not specified. Result will server from "/WEB-INF/content/".
*
* @author Vivek Patidar
*/

@Namespace("/user")
public class CaseSecondAction {

    @Action(value = "/casesecond", results = { @Result(name = "success", location = "result.jsp") })
    public String execute() {
        return "success";
    }

}
  Case III: CaseThirdAction.java Namespace of the action is @Namespace (?/user?) Action defined at class level, @Action (value = ?/ casethird?) ResultPath is @ResultPath (value = ?/?) Result will render from /root/user folder.
import org.apache.struts2.convention.<wbr />annotation.Action;
import org.apache.struts2.convention.<wbr />annotation.Namespace;
import org.apache.struts2.convention.<wbr />annotation.Result;
import org.apache.struts2.convention.<wbr />annotation.ResultPath;

/**
* Action annotation is specified at class level and ResultPath annotation is
* also specified. Result will server from "/root/user/".
*
* @author Vivek Patidar
*/

@Namespace("/user")
@ResultPath("/")
@Action(value = "/casethird")
@Result(name = "success", location = "result.jsp")
public class CaseThirdAction {

    public String execute() {
        return "success";
    }

}
  Case IV: CaseFourthAction.java Namespace of the action is @Namespace (?/user?) Action defined at method level, @Action (value = ?/ casefourth?) ResultPath is @ResultPath (value = ?/?) Result will render from /root folder.
import org.apache.struts2.convention.<wbr />annotation.Action;
import org.apache.struts2.convention.<wbr />annotation.Namespace;
import org.apache.struts2.convention.<wbr />annotation.Result;
import org.apache.struts2.convention.<wbr />annotation.ResultPath;

/**
* Action annotation is specified at method level and ResultPath annotation is
* also specified. Result will serve from "/root/".
*
* @author Vivek Patidar
*/

@Namespace("/user")
@ResultPath("/")
public class CaseFourthAction {

    @Action(value = "/casefourth", results = { @Result(name = "success", location = "result.jsp") })
    public String execute() {
        return "success";
    }

}
  Case V: CaseFifthAction.java and CaseSixthAction.java Namespace is not defined. (If namespace is not defined then it is consider as default nameapce ?/?) Action defined at class level or method level. ResultPath is not defined. Result will render from /WEB-INF/content folder itself.
import org.apache.struts2.convention.<wbr />annotation.Action;
import org.apache.struts2.convention.<wbr />annotation.Result;

/**
* Namespace and ResultPath annotation is not specified and Action annotation is
* specified at method level. Result will serve from "/WEB-INF/content/".
*
* If Action annotation is specified at the class level then result also
* serve from "/WEB-INF/content/". see {@link CaseSixthAction.java}
*
*
* @author Vivek Patidar
*/

public class CaseFifthAction {

    @Action(value = "casefifth", results = { @Result(name = "success", location = "result.jsp") })
    public String execute() {
        return "success";
    }

}

 
import org.apache.struts2.convention.<wbr />annotation.Action;
import org.apache.struts2.convention.<wbr />annotation.Result;

/**
* Namespace and ResultPath annotation is not specified and Action annotation is
* specified at method level. Result will serve from "/WEB-INF/content/".
*
* If Action annotation is specified at the method level then the result also
* serve from "/WEB-INF/content/", See {@link CaseFifthAction.java}
*
* @author Vivek Patidar
*/

@Action("/casesixth")
@Result(name = "success", location = "result.jsp")
public class CaseSixthAction {

    public String execute() {
        return "success";
    }

}

What happen if the action was not found in namespace?

If the action was not found in the namespace then struts will find it in the default namespace and other namespaces, and will serve from them. However here are some rules. If the action is available in the other namespace then it only be serve if action annotation is specified at method level, if action annotation is specified at class level then it will not be serve from other namespace url.

Here are some example :

  1. http://localhost:8080/AnnotationNamespace/user1/casefirst this will give error because action annotation is specified at class level in CaseFirstAction.java and there is no other method with this name in default namespace.
  2. http://localhost:8080/AnnotationNamespace/user1/casesecond will give the result because action annotation is specified at method level in CaseSecondAction.java.

If action is available in default namespace then action annotation place does not metter.

  1. http://localhost:8080/AnnotationNamespace/user/casefifth action is specified at method level.
  2. http://localhost:8080/AnnotationNamespace/user/casesixth action is specified at class level.

All the specified classes contains in the eclipse project and you can download it from Github . Download