Apache Struts still supports the familiar action-based MVC model, but a modern Struts application looks quite different from the old Struts 2.5 examples. Current Struts 7 applications use Jakarta EE APIs, require Java 17 or newer, and work perfectly well on Java 25.
This tutorial keeps the original Struts jQuery Ajax example intact conceptually: click a link in a JSP, send a value to a Struts action, render a small JSP response and place that response into a DIV without reloading the entire page.
Struts jQuery Ajax example
The application has four important pieces:
- A JSP page that creates the Ajax link.
- A Struts action that receives the request.
- A result JSP that renders the HTML fragment returned to the browser.
- Maven and Jakarta Servlet configuration that bootstraps the application.
The Struts jQuery plugin provides JSP tags that hide much of the JavaScript required to perform the asynchronous request and update the page.
Create the Struts jQuery Ajax link
Add the standard Struts tag library and the Struts jQuery tag library to the JSP. The <sj:head> tag initializes the browser-side resources used by the plugin.
The following page sends the value @cameronmcnz to the ajaxhello action. The returned HTML is inserted into the element whose ID is ajax-results.
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="sj" uri="/struts-jquery-tags" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Struts jQuery Ajax Example</title>
<sj:head />
</head>
<body>
<s:url var="ajaxLink" action="ajaxhello">
<s:param name="handle">@cameronmcnz</s:param>
</s:url>
<sj:a
id="hello-link"
href="%{ajaxLink}"
targets="ajax-results">
Say Hello to @cameronmcnz
</sj:a>
<div id="ajax-results">
<p>The Struts Ajax result will appear here.</p>
</div>
</body>
</html>
The Struts jQuery Ajax example updates part of the page without a full browser refresh.
Create the Struts action
The server-side component is still a normal Struts action. The jQuery plugin does not require a special type of action class.
This example uses Struts annotations and Java 25. The action receives the handle request property and returns SUCCESS, which forwards processing to the result JSP.
package com.mcnz.struts;
import org.apache.struts2.ActionSupport;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Result;
public class AjaxHelloAction extends ActionSupport {
private String handle;
@Action(
value = "/ajaxhello",
results = {
@Result(
name = SUCCESS,
location = "/results.jsp"
)
}
)
public String execute() {
IO.println("The handle is: " + handle);
return SUCCESS;
}
public String getHandle() {
return handle;
}
public void setHandle(String handle) {
this.handle = handle;
}
}The use of IO.println reflects the modern Java 25 console I/O API. In a production web application, structured application logging is normally preferable to writing diagnostic information directly to standard output.
Return the Ajax response
The result JSP does not need to render an entire HTML document. It only needs to generate the fragment that will replace the contents of ajax-results.
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<h2>
Hello <s:property value="handle" />
</h2>When the Ajax request completes, the plugin takes this HTML fragment and places it into the target DIV.
Modern Jakarta web.xml configuration
Modern Struts 7 applications use Jakarta EE rather than the old javax.servlet namespace. The Struts filter remains the entry point for incoming requests.
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
https://jakarta.ee/xml/ns/jakartaee
https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
version="6.0">
<display-name>Struts jQuery Ajax Example</display-name>
<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>Modern Struts Maven configuration
The original version of this tutorial used Struts 2.5, Java 8 and the old javax.servlet API. Those dependencies should not be copied into a new application.
For a modern project, use a current Struts 7 release, compile for Java 25 and use the Jakarta Servlet API. The Struts BOM keeps the official Struts modules on the same version.
<project xmlns="https://maven.apache.org/POM/4.0.0"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
https://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mcnz</groupId>
<artifactId>struts-jquery-ajax-example</artifactId>
<version>1.0.0</version>
<packaging>war</packaging>
<properties>
<maven.compiler.release>25</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<struts.version>7.2.1</struts.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-bom</artifactId>
<version>${struts.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-convention-plugin</artifactId>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
<scope>provided</scope>
</dependency>
<!--
Add a Struts jQuery plugin release that explicitly supports
the Struts major version used by your application.
-->
<dependency>
<groupId>com.jgeppert.struts2.jquery</groupId>
<artifactId>struts2-jquery-plugin</artifactId>
<version>YOUR_COMPATIBLE_VERSION</version>
</dependency>
</dependencies>
<build>
<finalName>struts-jquery-ajax-example</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.1</version>
<configuration>
<release>25</release>
</configuration>
</plugin>
</plugins>
</build>
</project>One dependency deserves special attention: the Struts jQuery plugin is maintained separately from Apache Struts. Do not assume an old plugin release intended for Struts 2.5 is binary-compatible with Struts 7. Choose a plugin release that explicitly supports the Struts version used by your project.
Run the modern Struts Ajax application
Package the application as a WAR and deploy it to a Jakarta Servlet 6 compatible server. Once the application starts, open the JSP and click the Ajax link.
The browser sends the request to AjaxHelloAction, Struts populates the handle property, the action forwards to results.jsp, and the Struts jQuery plugin inserts the returned fragment into the page.
The basic Struts Ajax request-response cycle remains simple even when the surrounding Java stack is modernized.
The important modernization point is that the basic Struts MVC pattern has not changed: a request targets an action, the action performs server-side work and a result renders the response. What has changed is the surrounding platform. New applications should use supported Struts releases, Jakarta APIs and a current Java runtime rather than carrying forward Struts 2.5 and Java 8 dependencies.