Things We Need
Before we starts with our first Hello World Struts 2 Example below, we will need few tools.
- JDK 1.5 above
- Tomcat 5.x above or any other container (Glassfish, JBoss, Websphere, Weblogic etc)
- Eclipse 3.2.x above
- Apache Struts2 JAR files: . Following are the list of JAR files required for this application.
- commons-logging-1.0.4.jar
- freemarker-2.3.8.jar
- ognl-2.6.11.jar
- struts2-core-2.0.12.jar
- xwork-2.0.6.jar
Note that depending on the current version of Struts2, the version number of above jar files may change.
Our Goal
Our goal is to create a basic Struts2 application with a Login page.
User will enter login credential and if authenticated successfully she
will be redirected to a Welcome page which will display message ” Howdy, <username>…!“. If user is not authenticated, she will be redirected back to the login page.
Getting Started
Let us start with our first Struts2 based application.
Open Eclipse and goto File -> New -> Project and select Dynamic Web Project in the New Project wizard screen.
(NOTE: need webtools pluggin for Eclipse see http://www.eclipse.org/webtools/
Currently, This software repository URL, http://download.eclipse.org/webtools/repository/helios/,
provides access to the releases of the Eclipse Web Tools Platform. Enter in this URL after bringing
up Help->Install New Software interface in Eclipse)
After selecting Dynamic Web Project, press Next.
Write the name of the project. For example StrutsHelloWorld. Once this is done, select the target runtime environment (e.g. Apache Tomcat v6.0 or
whatever later version you have). This is to run the project inside Eclipse environment. After this press Finish.
Once the project is created, you can see its structure in Project Explorer.
Now copy all the required JAR files in WebContent -> WEB-INF -> lib folder. (see here for ALL jar files of a 2.* verion of
Struts or download the lates)
Create this folder if it does not exists.
Mapping Struts2 in WEB.xml
As discussed in the previous article (Introduction to Struts2),
the entry point of Struts2 application will be the Filter defined
in
deployment descriptor (web.xml). Hence we will define an entry of org.apache.struts2.dispatcher.FilterDispatcher class in web.xml.
Open web.xml file which is under WEB-INF folder and copy paste following code.
01.
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
02.
03.
<
web-app
id
=
"WebApp_9"
version
=
"2.4"
06.
xsi:schemaLocation
=
"http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
>
07.
08.
<
display-name
>Struts2 Application</
display-name
>
09.
<
filter
>
10.
<
filter-name
>struts2</
filter-name
>
11.
<
filter-class
>
12.
13.
org.apache.struts2.dispatcher.FilterDispatcher
14.
</
filter-class
>
15.
</
filter
>
16.
<
filter-mapping
>
17.
<
filter-name
>struts2</
filter-name
>
18.
<
url-pattern
>/*</
url-pattern
>
19.
20.
</
filter-mapping
>
21.
<
welcome-file-list
>
22.
<
welcome-file
>Login.jsp</
welcome-file
>
23.
</
welcome-file-list
>
24.
25.
</
web-app
>
The above code in web.xml will map Struts2 filter with url /*. The
default url mapping for struts2 application will be /*.action.
Also note
that we have define Login.jsp as welcome file.
The Action Class
We will need an Action class that will authenticate our user and
holds the value for username and password. For this we will create a
package net.viralpatel.struts2 in the source folder. This package will contain the action file.
Create a class called LoginAction in net.viralpatel.struts2 package with following content.
01.
package
net.viralpatel.struts2;
02.
03.
public
class
LoginAction {
04.
private
String username;
05.
private
String password;
06.
07.
public
String execute() {
08.
09.
if
(
this
.username.equals(
"admin"
)
10.
&&
this
.password.equals(
"admin123"
)) {
11.
return
"success"
;
12.
}
else
{
13.
return
"error"
;
14.
}
15.
}
16.
17.
public
String getUsername() {
18.
return
username;
19.
}
20.
21.
public
void
setUsername(String username) {
22.
this
.username = username;
23.
}
24.
25.
public
String getPassword() {
26.
return
password;
27.
}
28.
29.
public
void
setPassword(String password) {
30.
this
.password = password;
31.
}
32.
}
Note that, above action class contains two fields, username and
password which will hold the values from form and also
contains an
execute() method that will authenticate the user. In this simple
example, we are checking if username is admin and password is admin123.
Also note that unlike Action class in Struts1, Struts2 action class is a simple POJO class with required attributes and method.
The execute() method returns a String value which will determine the
result page. Also, in Struts2
the name of the method is not fixed. In
this example we have define method execute(). You may want to define a
method authenticate() instead.
The ResourceBundle
ResourceBundle is very useful Java entity that helps in putting the
static content away from the source file. Most of the application
define
a resource bundle file such as ApplicationResources.properties file
which contains static messages such as Username or
Password and include
this with the application.
ResourceBundle comes handy when we want to add Internationalization (I18N) support to an application.
We will define an ApplicationResources.properties file for our
application. This property file should be present in WEB-INF/classes
folders
when the source is compiled. Thus we will create a source folder
called resources and put the ApplicationResources.properties file in it.
To create a source folder, right click on your project in Project Explorer and select New -> Source Folder.
Specify folder name resources and press Finish.
Create a file ApplicationResources.properties under resources folder.
Copy following content in ApplicationResources.properties.
1.
label.username= Username
2.
label.password= Password
3.
label.login= Login
The JSP
We will create two JSP files to render the output to user. Login.jsp will be the starting point of our application which will contain a simple login form with username and password. On successful authentication, user will be redirected to Welcome.jsp which will display a simple welcome message.
Create two JSP files Login.jsp and Welcome.jsp in WebContent folder of your project. Copy following content into it.
Login.jsp
01.
<%@ page contentType="text/html; charset=UTF-8"%>
02.
<%@ taglib prefix="s" uri="/struts-tags"%>
03.
<
html
>
04.
<
head
>
05.
06.
<
title
>Struts 2 - Login Application | ViralPatel.net</
title
>
07.
</
head
>
08.
09.
<
body
>
10.
<
h2
>Struts 2 - Login Application</
h2
>
11.
<
s:actionerror
/>
12.
<
s:form
action
=
"login.action"
method
=
"post"
>
13.
14.
<
s:textfield
name
=
"username"
key
=
"label.username"
size
=
"20"
/>
15.
<
s:password
name
=
"password"
key
=
"label.password"
size
=
"20"
/>
16.
17.
<
s:submit
method
=
"execute"
key
=
"label.login"
align
=
"center"
/>
18.
</
s:form
>
19.
</
body
>
20.
</
html
>
Welcome.jsp
01.
<%@ page contentType="text/html; charset=UTF-8"%>
02.
<%@ taglib prefix="s" uri="/struts-tags"%>
03.
<
html
>
04.
05.
<
head
>
06.
<
title
>Welcome</
title
>
07.
</
head
>
08.
09.
<
body
>
10.
<
h2
>Howdy, <
s:property
value
=
"username"
/>...!</
h2
>
11.
12.
</
body
>
13.
</
html
>
Note that we have used struts2 <s:> tag to render the textboxes and labels. Struts2 comes with a powerful built-in tag library to render UI elements more efficiently.
The struts.xml file
Struts2 reads the configuration and class definition from an xml file called struts.xml. This file is loaded from the classpath of the project. We will define struts.xml file in the resources folder. Create file struts.xml in resources folder.
Copy following content into struts.xml.
01.
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
02.
<!DOCTYPE struts PUBLIC
03.
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
05.
06.
<
struts
>
07.
<
constant
name
=
"struts.enable.DynamicMethodInvocation"
08.
value
=
"false"
/>
09.
<
constant
name
=
"struts.devMode"
value
=
"false"
/>
10.
11.
<
constant
name
=
"struts.custom.i18n.resources"
12.
value
=
"ApplicationResources"
/>
13.
14.
<
package
name
=
"default"
extends
=
"struts-default"
namespace
=
"/"
>
15.
16.
<
action
name
=
"login"
17.
class
=
"net.viralpatel.struts2.LoginAction"
>
18.
<
result
name
=
"success"
>Welcome.jsp</
result
>
19.
<
result
name
=
"error"
>Login.jsp</
result
>
20.
21.
</
action
>
22.
</
package
>
23.
</
struts
>
Note that in above configuration file, we have defined Login action of our application. Two result paths are mapped with LoginAction depending on the outcome of execute() method. If execute() method returns success, user will be redirected to Welcome.jsp else to Login.jsp.
Also note that a constant is specified with name struts.custom.i18n.resources. This constant specify the resource bundle file that we created in above steps. We just have to specify name of resource bundle file without extension (ApplicationResources without .properties).
Our LoginAction contains the method execute() which is the default method getting called by Sturts2. If the name of method is different, e.g. authenticate(); then we should specify the method name in <action> tag.
1.
<
action
name
=
"login"
method
=
"authenticate"
2.
class
=
"net.viralpatel.struts2.LoginAction"
>
Almost Done
We are almost done with the application. You may want to run the
application now and see the result yourself. I assume you have already
configured Tomcat in eclipse. All you need to do:
Open Server view from Windows -> Show View -> Server. Right click
in this view and select New -> Server and add your server details.
To run the project, right click on Project name from Project Explorer
and select Run as -> Run on Server (Shortcut: Alt+Shift+X, R)
But there is one small problem. Our application runs perfectly fine at this point. But when user enters wrong credential, she is redirected to Login page. But no error message is displayed. User does not know what just happened. A good application always show proper error messages to user. So we must display an error message Invalid Username/Password. Please try again when user authentication is failed.
Final Touch
To add this functionality first we will add the error message in our ResourceBundle file.
Open ApplicationResources.properties and add an entry for error.login in it. The final ApplicationResources.properties will look like:
1.
label.username= Username
2.
label.password= Password
3.
label.login= Login
4.
error.login= Invalid Username/Password. Please try again.
Also we need to add logic in LoginAction to add error message if user is not authenticated. But there is one problem. Our error message is specified in ApplicationResources.properties file. We must specify key error.login in LoginAction and the message should be displayed on JSP page.
For this we must implement com.opensymphony.xwork2.TextProvider interface which provides method getText(). This method returns String value from resource bundle file. We just have to pass the key value as argument to getText() method. The TextProvider interface defines several method that we must implement in order to get hold on getText() method. But we don’t want to spoil our code by adding all those methods which we do not intend to use. There is a good way of dealing with this problem.
Struts2 comes with a very useful class com.opensymphony.xwork2.ActionSupport. We just have to extend our LoginAction class with this class and directly use methods such as getText(), addActionErrors() etc. Thus we will extend the LoginAction class with ActionSupport class and add the logic for error reporting into it. The final code in LoginAction must look like:
01.
package
net.viralpatel.struts2;
02.
03.
import
com.opensymphony.xwork2.ActionSupport;
04.
05.
public
class
LoginAction
extends
ActionSupport {
06.
private
String username;
07.
private
String password;
08.
09.
public
String execute() {
10.
11.
if
(
this
.username.equals(
"admin"
)
12.
&&
this
.password.equals(
"admin123"
)) {
13.
return
"success"
;
14.
}
else
{
15.
addActionError(getText(
"error.login"
));
16.
return
"error"
;
17.
}
18.
}
19.
20.
public
String getUsername() {
21.
return
username;
22.
}
23.
24.
public
void
setUsername(String username) {
25.
this
.username = username;
26.
}
27.
28.
public
String getPassword() {
29.
return
password;
30.
}
31.
32.
public
void
setPassword(String password) {
33.
this
.password = password;
34.
}
35.
}
And that’s it. Our first Hello World Struts2 Application is now ready.
That’s All Folks
Execute the application in Eclipse and run it in your favorite browser.
Login page
Welcome page
Login page with error
Download Source Code
Click here to download Source Code without JAR files (9KB).