Struts2 First Example – Hello World with Maven Setup
Apache Struts2 is an MVC framework for building Java web applications. It uses a front-controller filter, an XML action mapping file (struts.xml), and Action classes instead of plain Servlets. This tutorial builds a complete first Struts2 application from scratch and explains how to display values in JSP using both HTML EL and Struts2 tags.
How Struts2 Works
Browser Request
↓
web.xml → StrutsPrepareAndExecuteFilter (intercepts all /*)
↓
struts.xml → maps URL to Action class and method
↓
Action class (plain POJO with execute() method)
↓
Returns result name ("success", "error", etc.)
↓
struts.xml → maps result name to JSP file
↓
JSP → renders response
Maven Dependencies (pom.xml)
<dependencies>
<!-- Struts2 core -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.5.33</version>
</dependency>
<!-- Servlet API (provided by the container) -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- JSTL -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<packaging>war</packaging>
Project Structure
src/
main/
java/
com/java9r/
HelloAction.java
resources/
struts.xml
webapp/
WEB-INF/
web.xml
index.jsp
success.jsp
web.xml – Register the Struts2 Filter
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<display-name>Struts2 First Example</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- Struts2 front-controller filter -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
HelloAction.java – The Action Class
An Action class is a plain POJO. Field names become the form parameter names. The execute() method runs when the action is invoked and returns a result name string.
package com.java9r;
public class HelloAction {
private String name;
private int age;
private String city;
// execute() is called by default when no method is specified
public String execute() {
// Business logic goes here if needed
return "success";
}
// Getters and setters — Struts2 uses these for data binding
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public String getCity() { return city; }
public void setCity(String city) { this.city = city; }
}
struts.xml – Action Mapping
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<constant name="struts.devMode" value="true"/>
<constant name="struts.enable.DynamicMethodInvocation" value="false"/>
<package name="default" namespace="/" extends="struts-default">
<!-- URL /hello → HelloAction.execute() → success.jsp -->
<action name="hello" class="com.java9r.HelloAction">
<result name="success">/success.jsp</result>
<result name="error">/index.jsp</result>
</action>
</package>
</struts>
index.jsp – Input Form
Struts2 provides its own tag library (prefix="s"). Struts2 tags integrate automatically with the action's fields and handle OGNL expressions.
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
<head>
<title>Hello Struts2</title>
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container mt-4">
<h3>Struts2 First Example</h3>
<hr>
<!-- action="hello" maps to the <action name="hello"> in struts.xml -->
<s:form action="hello" method="post" cssClass="col-md-6">
<div class="mb-3">
<label>Name:</label>
<!-- s:textfield name="name" → sets HelloAction.name via setName() -->
<s:textfield name="name" cssClass="form-control" />
</div>
<div class="mb-3">
<label>Age:</label>
<s:textfield name="age" cssClass="form-control" />
</div>
<div class="mb-3">
<label>City:</label>
<s:textfield name="city" cssClass="form-control" />
</div>
<s:submit value="Submit" cssClass="btn btn-primary" />
</s:form>
</div>
</body>
</html>
success.jsp – Displaying Values (Three Ways)
Struts2 exposes action fields to JSP via the Value Stack. There are three ways to read them:
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
<head>
<title>Result</title>
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container mt-4">
<h3>Three Ways to Display Values in Struts2</h3>
<hr>
<h5>1. HTML tag + JSP EL expression: ${name}</h5>
<!--
Standard JSP Expression Language.
Reads from request attributes / value stack.
CSS class added directly to HTML input.
-->
<input type="text" class="form-control mb-2" value="${name}">
<input type="text" class="form-control mb-2" value="${age}">
<input type="text" class="form-control mb-2" value="${city}">
<hr>
<h5>2. Struts2 tag: value="%{name}"</h5>
<!--
OGNL expression inside Struts2 tag.
%{...} is the OGNL evaluator syntax.
cssClass= is the Struts2 attribute that renders as class= in HTML.
-->
<s:textfield value="%{name}" cssClass="form-control mb-2" />
<s:textfield value="%{age}" cssClass="form-control mb-2" />
<s:textfield value="%{city}" cssClass="form-control mb-2" />
<hr>
<h5>3. s:property tag (read-only display)</h5>
<!--
s:property renders the value as text (no input box).
Equivalent to writing ${name} in a span.
-->
<p>Name: <s:property value="name" /></p>
<p>Age: <s:property value="age" /></p>
<p>City: <s:property value="city" /></p>
</div>
</body>
</html>
HTML Tag vs Struts2 Tag – Key Differences
| Feature | HTML tag + EL ${name} |
Struts2 tag %{name} |
|---|---|---|
| Expression language | JSP EL | OGNL (more powerful) |
| CSS class attribute | class="form-control" |
cssClass="form-control" |
| Automatic validation display | No | Yes (shows field errors) |
| Theme wrapper HTML | None — pure HTML | Adds extra div/label by default (use theme="simple" to suppress) |
| Complex object access | ${user.address.city} |
%{user.address.city} |
struts.xml Result Types
<!-- Default: forward to a JSP -->
<result name="success">/success.jsp</result>
<!-- Redirect to another URL -->
<result name="success" type="redirect">/index.jsp</result>
<!-- Redirect to another Struts2 action -->
<result name="success" type="redirectAction">
<param name="actionName">listUsers</param>
</result>
<!-- Return JSON (requires struts2-json-plugin) -->
<result type="json">
<param name="root">responseMap</param>
</result>
Summary
A Struts2 application has three main pieces: web.xml registers the StrutsPrepareAndExecuteFilter to intercept all requests, struts.xml maps URLs to Action classes and maps result names to JSP files, and the Action class is a plain POJO whose fields are bound from HTTP parameters via getter/setter pairs. In JSP, use ${name} (JSP EL) or <s:property value="name"/> (Struts2 tag) to display action field values. Struts2 tags add extra features like field-level validation messages, but require cssClass instead of the standard class attribute.
Comments