Before you begin
- Follow the blog post Starting web development with Maven and Eclipse to create a web application. This blog shows how we can extend that basic web application to add Struts2 support.
- This blog post assumes that you are familiar with Struts2 already. If that is not the case, this would be the good time to do so. The official Apache Struts 2 website is a good place to start. Get a free copy of the mini book Starting Struts 2. Thanks to Ian Roughley and InfoQ.com for making this great mini book available for free.
Begin web application development using Struts2
Now that you have your very basic web app running, it’s time to add the Struts2 support to it. We are going to develop the classic “Hello World” application, but with a twist. Our Hello World application prints “Hello user’s name” along with the other user information, if it is included in the request. If user’s name is not specified, “Hello World” is displayed as usual.
Add Struts2 dependencies to pom.xml
Before we start actual development, let’s add Struts2 dependencies to the maven pom file. The complete pom.xml is listed below.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.rajandesai.example</groupId> <artifactId>webapp</artifactId> <version>1.0.0-SNAPSHOT</version> <packaging>jar</packaging> <name>webapp</name> <url>http://maven.apache.org</url> <!-- Shared version number properties --> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <struts2.version>2.1.8</struts2.version> <junit.version>4.4</junit.version> <log4j.version>1.2.14</log4j.version> </properties> <dependencies> <!-- Struts 2 --> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>${struts2.version}</version> </dependency> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-spring-plugin</artifactId> <version>${struts2.version}</version> </dependency> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-junit-plugin</artifactId> <version>${struts2.version}</version> </dependency> <!-- Servlet & Jsp --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.4</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> <!-- Other dependencies --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> <scope>runtime</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.0.2</version> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.1-beta-1</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <version>6.0.0</version> <configuration> <contextPath>/</contextPath> <scanIntervalSeconds>3</scanIntervalSeconds> <scanTargets> <scanTarget> src/main/webapp/WEB-INF/web.xml </scanTarget> </scanTargets> </configuration> </plugin> </plugins> <finalName>webapp</finalName> </build> </project>
Define the Domain Object (Model)
This Hello World application needs access to the user data sent with the request. Let’s define a domain object (or model) that can be used to store the form or request parameters. We will use the ModelDriven
action so that the Struts2 framework can populate this model for us.
package com.rajandesai.example.webapp.model; import java.io.Serializable; /** * Defines a model that represents a user in the system. */ public class User implements Serializable { private static final long serialVersionUID = -2230673925164485629L; private String name = null; private String zip = null; private int age; private char gender; public final String getName() { return name; } public final void setName(String name) { this.name = name; } public final String getZip() { return zip; } public final void setZip(String zip) { this.zip = zip; } public final int getAge() { return age; } public final void setAge(int age) { this.age = age; } public final char getGender() { return gender; } public final void setGender(char gender) { this.gender = gender; } }
Define the Action
Let’s define an action that handles the “Hello World” request. This implementation extends the ActionSupport
class that provides default implementation of the execute
. Our action also implements three other interfaces that are requires for the specific purposes:
ServletRequestAware
provides access to theHttpServletRequest
object.Preparable
interface provides a callback that is called beforeexecute
method is called. This can be used to for setup, configuration or pre-population of data before the action is executed.ModelDriven
interface, when combined with Struts2ParametersInterceptor
andModelDrivenInterceptor
, allows theHttpServletRequest
attributes to be set in the model or the action it self.
package com.rajandesai.example.webapp.action; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.interceptor.ServletRequestAware; import com.nexage.mediation.gateway.model.User; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; import com.opensymphony.xwork2.Preparable; /** * Action implementation that handles the Hello World requests. */ public class HelloAction extends ActionSupport implements ModelDriven, Preparable, ServletRequestAware { private static final long serialVersionUID = -3670063011948002290L; private User user; private HttpServletRequest request; public Object getModel() { return user; } public void prepare() throws Exception { //We can add logic to see if the user exists or not... user = new User(); } public void setServletRequest(HttpServletRequest httpServletRequest) { request = httpServletRequest; } //--------------------------- Getters/Setters ----------------------------- // Providing these getters and setters for the Domain object (model) allows // access to it in the view (JSP) /** * @return the user */ public final User getUser() { return user; } /** * @param user the user to set */ public final void setUser(User user) { this.user = user; } }
Define the Hello World view (JSP)
When the "Hello World" application processes the request successfully, hello.jsp
is displayed.
<%@ page contentType="text/html; charset=UTF-8" %> <%@ taglib prefix="s" uri="/struts-tags" %> <html> <head> <title>Hello World with a Twist</title> </head> <body> <h1>Hello<s:if test="%{user.name != null}"> <s:property value="user.name" /> <hr/> <h2>Other Details</h2> <h4>You Name : <s:property value="user.name" /></h4> <h4>You Age : <s:property value="user.age" /></h4> <h4>You Gender : <s:property value="user.gender" /></h4> <h4>You Zip : <s:property value="user.zip" /></h4> <hr/> </s:if> <s:else> World</s:else></h1> </body> </html>
Configure the Action
We need to configure the action before invoking it from the browser. This is done via struts.xml file.
In Struts2 the package
element is used to group the actions.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <include file="struts-default.xml"/> <constant name="struts.enable.DynamicMethodInvocation" value="false" /> <constant name="struts.devMode" value="true" /> <constant name="struts.objectFactory" value="struts" /> <package name="helloworld" namespace="/hello" extends="struts-default"> <action name="hello" class="com.rajandesai.example.webapp.action.HelloAction"> <result>/WEB-INF/example/hello.jsp</result> </action> <!-- Add additional "example" package actions here. --> </package> <!-- Add addition packages and configuration here. --> </struts>
Configure web.xml
Lastly, configure the web.xml
to support Struts2 filters.
<?xml version="1.0" encoding="UTF-8"?> <web-app id="web-app" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>Simple Hello World App using Struts2</display-name> <filter> <filter-name>struts-cleanup</filter-name> <filter-class>org.apache.struts2.dispatcher.ActionContextCleanUp</filter-class> </filter> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts-cleanup</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
Run the application
Now that we have all the pieces put together, it's time to test the application now.
In the command prompt, run mvn jetty:run
command in your project directory.
And then in the browser, try these sample URLs to test the application:
-
Hello World: http://localhost:8080/hello/hello.action
-
Hello World with the twist: http://localhost:8080/hello/hello.action?name=John%20Doe&zip=02451&age=30&gender=M
Conclusion
Struts2 is one of the most popular frameworks for developing java based web applications. Hope this gets you started with the Struts2 development quickly. Next, I am going to figure out how to add Spring support to the Struts2 application.
Source code is available here.
Discussion
No comments yet.