Struts 2 Hello World Annotation Example

In this tutorials, it will reuse the previous Strust 2 Hello World (XML version) example, and convert it into annotation version.

Struts 2 Annotation Concept

The Struts 2 annotation is supported by Struts 2 convention plugin, So, you have to understand the magic behind its “Scanning Methodology” and “Naming Converter” mechanism.

1. Scanning Methodology

Many Struts 2 articles or books stated that you can configure the filter’s “init-param” or “struts.convention.action.packages” to tell Struts 2 where to scan the annotated classes. For example,

web.xml


<filter>
  <filter-name>struts2</filter-name>
  <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
  <init-param>
	<param-name>actionPackages</param-name>
	<param-value>com.mkyong.common</param-value>
  </init-param>
</filter>

From my testing (Struts2 version 2.1.6 and 2.1.8), this is not true, no matter what you put in the “param-value” or “struts.convention.action.packages“, Struts 2 will just ignore it and scan the specified folders named struts, struts2, action or actions only.

Here’s how the scanning work

  1. Scan the annotated classes which located at the packaged named “struts, struts2, action or actions“.
  2. Next, scan the file which match either of the following criteria :
    • Implemented the com.opensymphony.xwork2.Action interface.
    • Extends the com.opensymphony.xwork2.ActionSupport class.
    • File name ends with Action (e.g UserAction, LoginAction).

See this Struts 2 convention plugin documentation.

2. Naming Converter

Struts 2 convention plugin will convert all the annotated action file name to a specified format.

For example : LoginAction.java

  1. First, remove the “Action” word at the end of the file name, if present.
  2. Second, convert the first letter of the file name to lowercase.

So, After removing the ending and converting the case of the first letter, the LoginAction.action will change to login.action.

The Struts 2 convention plugin’s “scanning methodology” and “naming converter” features are really bring a lot of conveniences and benefits, only if your Struts 2 project is following the naming convention properly; otherwise it will be a total disaster.

Struts 2 Annotation example

It’s time to start the conversion process.

Final project structure

Struts2 hello world annotation

1. Update pom.xml

To use the Struts 2 annotation feature, you need to download the struts2-convention-plugin.jar.
pom.xml


...
    <dependency>
          <groupId>org.apache.struts</groupId>
	  <artifactId>struts2-core</artifactId>
	  <version>2.1.8</version>
    </dependency>
	
    <dependency>
          <groupId>org.apache.struts</groupId>
	  <artifactId>struts2-convention-plugin</artifactId>
	  <version>2.1.8</version>
    </dependency>
...

2. LoginAction

Create a LoginAction extends ActionSupport and do nothing, the ActionSupport default return a “success” string, which will match the @Result and redirect to “pages/login.jsp“.

Annotation version


package com.mkyong.user.action;

import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.ResultPath;

import com.opensymphony.xwork2.ActionSupport;

@Namespace("/User")
@ResultPath(value="/")
@Result(name="success",location="pages/login.jsp")
public class LoginAction extends ActionSupport{

}

XML equivalent


<package name="user" namespace="/User" extends="struts-default">
	<action name="Login">
		<result>pages/login.jsp</result>
	</action>
</package>

3. WelcomeUserAction

Override the execute() method and specified the @Action and @Result annotation.

Annotation version


package com.mkyong.user.action;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.ResultPath;

import com.opensymphony.xwork2.ActionSupport;

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

	private String username;
	 
	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	@Action(value="Welcome", results={
		@Result(name="success",location="pages/welcome_user.jsp")
	})
	public String execute() {

		return SUCCESS;

	}
}

XML equivalent


<package name="user" namespace="/User" extends="struts-default">
   <action name="Welcome" class="com.mkyong.user.action.WelcomeUserAction">
	<result name="SUCCESS">pages/welcome_user.jsp</result>
   </action>
</package>
The Struts 2 annotations – @Action, @Result and @Namespace are self-explanatory, you can always compare it with the XML equivalent. The @ResultPath may need a bit explanation, see this @ResultPath example.

4. JSP view pages

Normal JSP view pages to accept a username and password, and redirect to a welcome page once the submit button is clicked.

login.jsp

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>



Struts 2 Hello World Annotation Example

welcome_user.jsp

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>



Struts 2 Hello World Annotation Example

Hello

5. struts.xml

No need to create struts.xml file, all classes are annotated.

6. web.xml

Just create a classic web.xml file and declared the FilterDispatcher filter as normal.


<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Struts 2 Web Application</display-name>
  
  <filter>
	<filter-name>struts2</filter-name>
	<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
  </filter>
  
  <filter-mapping>
	<filter-name>struts2</filter-name>
	<url-pattern>/*</url-pattern>
  </filter-mapping>
  
</web-app>

7. Run it

The LoginAction.action is changed to login.action, see “Naming Converter” above.
http://localhost:8080/Struts2Example/User/login.action

Struts 2 annotation login screen

http://localhost:8080/Struts2Example/User/Welcome.action

Struts 2 annotation welcome screen

Reference

  1. Struts 2 convention plugin documentation
  2. Strust 2 Hello World (XML version)

About the Author

author image
mkyong
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider make a donation to these charities.

Comments

Leave a Reply

avatar
newest oldest most voted
rakesh sharma
Guest
rakesh sharma

Hi I am using annotations in struts2 but getting exception. The beginning of the exception reads like this

Struts has detected an unhandled exception:

Messages:File:org/apache/struts2/impl/StrutsActionProxy.javaLine number:69

Stacktraces

java.lang.NullPointerException

org.apache.struts2.impl.StrutsActionProxy.getErrorMessage(StrutsActionProxy.java:69)

With the configurations in xml its working but not with the annotations

kapil
Guest
kapil

im not able to run struts2 annotation………its showing resourse is not available

struts2annotation
Guest
struts2annotation

I tried struts2 annotation. I got the error when I was deploying the project/starting server itself. I got exception in server like
Caused by: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException.
Please help me how to do it.
I tried by removing struts2-convention-plugin-2.1.6.jar, antlr-2.7.6.jar. That time when I was starting server I did not get any exception in server. Please help me how to resolve it?

Umesh Annegirikar
Guest
Umesh Annegirikar
Dear MKYONG I got the following exception stack i have copied the same libraries as that of the code sample given by you then also i got the same error i get following exception stack SEVERE: Exception starting filter struts2 Unable to load configuration. – bean – jar:file:/C:/Users/Umesh/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp1/wtpwebapps/Struts2HelloWorldAnnotation/WEB-INF/lib/struts2-core-2.1.8.jar!/struts-default.xml:47:178 at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:431) at org.apache.struts2.dispatcher.FilterDispatcher.init(FilterDispatcher.java:190) at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:295) at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:422) at org.apache.catalina.core.ApplicationFilterConfig.(ApplicationFilterConfig.java:115) at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4072) at org.apache.catalina.core.StandardContext.start(StandardContext.java:4726) at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057) at org.apache.catalina.core.StandardHost.start(StandardHost.java:840) at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057) at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463) at org.apache.catalina.core.StandardService.start(StandardService.java:525) at org.apache.catalina.core.StandardServer.start(StandardServer.java:754) at org.apache.catalina.startup.Catalina.start(Catalina.java:595) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414) Caused by: Unable to load configuration. – bean… Read more »
ravi
Guest
ravi

Hi Mkyong

How can I post a dynamic parameter with annotations?
So in your example given above say I need ID=POSTEDVALUe

@Namespace(“/User”)
@ResultPath(value=”/”)
@Result(name=”success”,location=”pages/login.jsp?id=DYNAMICVALUE”)
public class LoginAction extends ActionSupport{

}

Andrey
Guest
Andrey

Dear MKYONG,

I’m sorry I have lost code snippets from the previous post.
Below is the correct version.

b) am I correct that whenever you want to WRITE smth into Action bean, you link jsp and bean via ‘name’ attrubuted of the form tags, like

And whenever you READ smth out of Action bean on the jsp side you use

Thank you in advance

Andrey
Guest
Andrey
Dear MKYONG, Firstly, I want to thank you for the efforts you put in your really useful site. My gratitude is immense. Secondly, let me ask two rather basic questions: a) when LoginAction is addressed (via url like /login.action) what is actually done behined the curtains? I mean what method probably inherited from ActionSupport gets performed which redirects page flow to login.jsp? b) am I correct that whenever you want to WRITE smth into Action bean, you link jsp and bean via ‘name’ attrubuted of the form tags, like And whenever you READ smth out of Action bean on the… Read more »
satnam singh
Guest
satnam singh

thanks a lot dear a got this (naming conventions) point after struggling a whole day thanks again

sumi
Guest
sumi

if i change the package name it throws NullPointerException .what is solution for it.

Chuck
Guest
Chuck

Hi,

I was wondering is it possible to eliminate the need of web.xml all together? like in RESTEAsy.

Thank you,
Chuck

nam
Guest
nam

thanks so much, work great !

Fenil
Guest
Fenil

Thank you for your project. It helped me lot.
Thank you again.

Keith
Guest
Keith

Hmmmm,

I just get the following:

HTTP Status 404 – There is no Action mapped for namespace /User and action name Welcome

When going to
http://localhost/struts2App/User/Welcome.action

Umesh Annegirikar
Guest
Umesh Annegirikar

just check the name you given for action

girinformatique
Guest
girinformatique

I’ve the same error, and I didn’t touch the project after downloading….it happens also for other struts2 annotation projects that Ive created….something wrong with my system…I think…coz all things are in their places after comparing all source files with ones given in the tutorial!!!

Jeegar
Guest
Jeegar

Hi ,
I have done exactly what you mentioned in the above steps but still not able to run the jsp file , please advise me what could be for the same .

Regards,
Jeegare

Jeegar
Guest
Jeegar

I am not able to run your sample project , it says Cannot find the tag library descriptor for uri=”/struts-tags” %> in login.jsp

peterwkc
Guest
peterwkc

Hi, I’m tried to develop an application in struts2 but still fail because of this warning

WARN [org.apache.struts2.dispatcher.Dispatcher] (http-localhost-127.0.0.1-8080-1) Could not find action or result: No result defined for action com.peter.action.LoginAction and result success
at com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:376) [xwork-core-2.3.4.1.jar:2.3.4.1]

when i click the submit button

Héctor
Guest
Héctor

Hello,

First of all, thank you for the tutorial. It really helped me a lot to understand the basic concepts.

However, I have a question… The url in wich you access at first time is:
http://localhost:8080/Struts2Example/User/login.action
I think this URL is not too friendly, it would be great if I could just delete the login.action and let the path / as default.
How can you configure struts to execute the LoginAction as default each time the user access to the URL:
http://localhost:8080/Struts2Example/User/

Thank you in advance.

Al
Guest
JeremyLee
Guest
JeremyLee

we can tell the convention plugin to scan specified package by

<constant name="struts.convention.package.locators" value="myaction" />

The property “struts.convention.package.locators” ‘s default value is “action,actions,struts,struts2”, packages whose name end with one of these strings will be scanned for actions.

I hope this will be helpful to understand where the plugin to scan the actions.

Nil
Guest
Nil

Thanks! Very helpful content.

Alex
Guest
Alex

When I put my action classes in a jar and deploy the application then after calling the action it shows following error…

There is no Action mapped for namespace / and action name Login. – [unknown location]

Same thing works fine if I put action .class files in WEB-INF/classes folder.

Could you please help me on this…

JeremyLee
Guest
JeremyLee

configure your output folder in eclipse.

Mayank
Guest
Mayank

Hi Mkyong,

Thanks for providing such important tutorial for begginers of struts2.
I have tried your tutorials after downloading from from given link and add required jars.

Thats is running fine on weblogic 10, but i am facing one issue when i deloyed that application as exploded way it was running fine but i want ot deploy the same as packahed way (as war file). it fails to find annoted action and gives me errors like no action mapped for give url.

Please help me out .

Thanks
Mayank

trackback
Maven – Convenciones – Estructura de carpetas | Lycka Bonita

[…] Image seen on mkyong.com. […]

yy
Guest
yy

also got the exception “There is no Action mapped for namespace /User and action name”

then moved the action class to package my.actions, and problem resolved

trackback
Struts 2 Tutorials

[…] Struts 2 Hello World (Annotation version) Struts 2 hello world example with annotation. […]

akki
Guest
akki

hi…i dont wanna use pom configuration file and want to implement it throungh struts2 annotation only….whn i did it myself i am getting an error as

HTTP Status 404 – There is no Action mapped for namespace /User and action name login.
plzz help me out

Tapio Niemela
Guest
Tapio Niemela

hey, and thanks for clear tutorial/example..

Do you happen to know what should URL look like when calling “camel-case” action class. Like MyLoginAction instead of LoginAction. I tried to use URLs myLogin.action and MyLogin.action and either one didn’t work..

Cristiano
Guest
Cristiano

Where is the complete pom.xml?
Should I add library to it? It would be nice to have the list of jarS you are using!

momo
Guest
momo

the package name is actions not package sorry

momo
Guest
momo
until now i did’nt successe to do an exemple of annotation, i use eclips 3.4 gynamed an pache tomcat, i have a pcage that his name is package in the src and i have a foldr jsp in web content , where i have may jsp with form and action refer to my action , my classe actio name is WelcomUser implement Action support,mau action name is actionUser.action in the form action, in the web xml i put in the web.xml actionPackages actions the jsp file ex-annotation the javas classe package actions; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Result; import org.apache.struts2.convention.annotation.Namespace; import com.opensymphony.xwork2.ActionSupport;… Read more »