//
you're reading...

Development

Starting Struts2 web application development (using Maven2 and Eclipse)

Before you begin

  1. 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.
  2. 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:

  1. ServletRequestAware provides access to the HttpServletRequest object.
  2. Preparable interface provides a callback that is called before execute method is called. This can be used to for setup, configuration or pre-population of data before the action is executed.
  3. ModelDriven interface, when combined with Struts2 ParametersInterceptor and ModelDrivenInterceptor, allows the HttpServletRequest 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.
Run Application

And then in the browser, try these sample URLs to test the application:

  1. Hello World: http://localhost:8080/hello/hello.action
    Boring Hello World
  2. Hello World with the twist: http://localhost:8080/hello/hello.action?name=John%20Doe&zip=02451&age=30&gender=M
    Twisted Hello World

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.

Post a Comment


*

Categories