
Struts Tutorial for Beginners
Struts is an open-source web application framework that follows the Model-View-Controller (MVC) architectural pattern, developed by the Apache Software Foundation to streamline Java-based web development. For developers dealing with enterprise-level applications, Struts provides a structured approach to building maintainable, scalable web applications while handling the complexities of HTTP request processing, form validation, and view rendering. This tutorial will guide you through the fundamentals of Struts, from basic setup to advanced features, covering practical implementation strategies, common troubleshooting scenarios, and real-world deployment patterns that you’ll encounter in production environments.
Understanding Struts Architecture and Core Components
Struts operates on the MVC pattern, where the framework acts as the controller layer, managing HTTP requests and coordinating between your business logic (Model) and presentation layer (View). The core architecture revolves around several key components that work together seamlessly.
The ActionServlet serves as the front controller, intercepting all requests matching configured URL patterns. When a request arrives, it’s processed through a chain of components including RequestProcessor, Action classes, and ActionForms. The framework then forwards the request to appropriate JSP pages or other view technologies based on ActionMapping configurations.
Here’s how the request flow works internally:
- Client sends HTTP request to the web container
- ActionServlet intercepts the request based on URL mapping
- RequestProcessor determines the appropriate Action class
- ActionForm populates and validates form data if present
- Action class executes business logic and returns ActionForward
- Framework forwards to the designated view component
- Response is rendered and sent back to the client
The framework’s strength lies in its declarative configuration approach using struts-config.xml, which centralizes application flow control and makes debugging significantly easier compared to scattered servlet mappings.
Step-by-Step Struts Application Setup
Setting up a Struts application requires specific JAR files, configuration files, and directory structure. Start by downloading Struts from the official Apache Struts website and ensure you have a servlet container like Tomcat or Jetty installed on your development machine.
Create the basic project structure:
struts-app/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ ├── action/
│ │ │ ├── form/
│ │ │ └── model/
│ │ ├── resources/
│ │ └── webapp/
│ │ ├── WEB-INF/
│ │ │ ├── web.xml
│ │ │ ├── struts-config.xml
│ │ │ └── lib/
│ │ └── jsp/
└── pom.xml (if using Maven)
Configure your web.xml with the ActionServlet:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
version="3.0">
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
Create your struts-config.xml file to define application flow:
<?xml version="1.0" encoding="UTF-8"?>
<struts-config>
<form-beans>
<form-bean name="userForm"
type="com.example.form.UserForm"/>
</form-beans>
<action-mappings>
<action path="/user"
type="com.example.action.UserAction"
name="userForm"
scope="request"
validate="true"
input="/jsp/userForm.jsp">
<forward name="success" path="/jsp/userSuccess.jsp"/>
<forward name="failure" path="/jsp/userError.jsp"/>
</action>
</action-mappings>
</struts-config>
Now create a sample ActionForm class:
package com.example.form;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionError;
import javax.servlet.http.HttpServletRequest;
public class UserForm extends ActionForm {
private String username;
private String email;
public ActionErrors validate(ActionMapping mapping,
HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
if (username == null || username.trim().length() == 0) {
errors.add("username", new ActionError("error.username.required"));
}
if (email == null || !email.contains("@")) {
errors.add("email", new ActionError("error.email.invalid"));
}
return errors;
}
// Getters and setters
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
}
Implement the corresponding Action class:
package com.example.action;
import com.example.form.UserForm;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class UserAction extends Action {
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
UserForm userForm = (UserForm) form;
// Business logic here
String username = userForm.getUsername();
String email = userForm.getEmail();
// Simulate processing
if (username.equals("admin")) {
request.setAttribute("message", "Welcome Administrator!");
return mapping.findForward("success");
} else {
request.setAttribute("error", "Invalid credentials");
return mapping.findForward("failure");
}
}
}
Real-World Implementation Examples
Enterprise applications often require more sophisticated patterns than basic form processing. Here’s a practical example of implementing a user management system with database integration and session handling.
For database operations, integrate Struts with your preferred ORM or DAO pattern:
public class UserAction extends Action {
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
UserForm userForm = (UserForm) form;
UserDAO userDAO = new UserDAO();
try {
User user = userDAO.findByUsername(userForm.getUsername());
if (user != null && user.isActive()) {
HttpSession session = request.getSession();
session.setAttribute("currentUser", user);
session.setAttribute("loginTime", new Date());
// Log successful login
Logger.getLogger(UserAction.class).info(
"User " + user.getUsername() + " logged in successfully"
);
return mapping.findForward("dashboard");
}
} catch (SQLException e) {
Logger.getLogger(UserAction.class).error("Database error", e);
ActionErrors errors = new ActionErrors();
errors.add(ActionErrors.GLOBAL_ERROR,
new ActionError("error.database.unavailable"));
saveErrors(request, errors);
}
return mapping.findForward("login");
}
}
For applications requiring high availability and scalability, consider these deployment patterns on dedicated servers or VPS hosting:
- Load balancing with session replication across multiple Tomcat instances
- Database connection pooling with proper timeout configurations
- Caching strategies using Ehcache or Redis for form data and user sessions
- CDN integration for static resources like CSS, JavaScript, and images
Framework Comparison and Migration Considerations
Understanding how Struts compares to modern alternatives helps in making informed architectural decisions:
Feature | Struts 1.x | Spring MVC | JSF | Struts 2 |
---|---|---|---|---|
Learning Curve | Moderate | Steep | Moderate | Easy |
Configuration | XML-heavy | Annotation-based | Mixed | Convention over configuration |
Performance | Good | Excellent | Average | Good |
Community Support | Limited | Very Active | Active | Active |
Testing Support | Basic | Excellent | Good | Good |
Performance benchmarks show that Struts applications typically handle 500-1000 concurrent requests efficiently on standard hardware configurations. However, memory usage can become a concern with complex ActionForm hierarchies, averaging 15-25MB per 100 concurrent sessions.
Migration strategies from legacy Struts applications often involve:
- Gradual refactoring of Action classes to Spring Controllers
- Converting ActionForms to POJOs with validation annotations
- Replacing Struts tags with modern template engines like Thymeleaf
- Implementing RESTful endpoints for AJAX functionality
Best Practices and Common Troubleshooting
Successful Struts applications follow specific patterns that prevent common runtime issues. Always implement proper exception handling in your Action classes, as unhandled exceptions can cause the entire request processing chain to fail.
Memory management becomes critical in high-traffic applications. Avoid storing large objects in ActionForms, and always clean up resources in finally blocks:
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = DataSourceManager.getConnection();
stmt = conn.prepareStatement("SELECT * FROM users WHERE id = ?");
stmt.setInt(1, userId);
rs = stmt.executeQuery();
// Process results
} catch (SQLException e) {
Logger.getLogger(getClass()).error("Database operation failed", e);
throw new Exception("Unable to process request", e);
} finally {
if (rs != null) try { rs.close(); } catch (SQLException ignored) {}
if (stmt != null) try { stmt.close(); } catch (SQLException ignored) {}
if (conn != null) try { conn.close(); } catch (SQLException ignored) {}
}
return mapping.findForward("success");
}
Common issues and their solutions:
- ActionForm not populating: Check parameter names match form field names exactly, and ensure proper getter/setter methods
- Forward not found errors: Verify forward names in struts-config.xml match those used in Action classes
- Validation not triggering: Ensure validate=”true” in action mapping and ActionForm.validate() returns non-empty ActionErrors
- Session timeout issues: Configure session timeout in web.xml and handle session expiration gracefully
- Character encoding problems: Set up filters for UTF-8 encoding and ensure database charset compatibility
Security considerations include input validation at multiple levels, CSRF protection using tokens, and proper session management. Always validate data in both ActionForm.validate() and your business logic layer, as client-side validation can be bypassed.
For production deployments, enable request logging and monitoring. Configure your application server with appropriate heap sizes and garbage collection settings. Applications running on modern hardware typically require 512MB-2GB heap space depending on concurrent user load and session data complexity.
Debug configurations should include detailed logging for org.apache.struts packages, and consider using profiling tools like JProfiler or VisualVM to identify performance bottlenecks in Action processing chains.

This article incorporates information and material from various online sources. We acknowledge and appreciate the work of all original authors, publishers, and websites. While every effort has been made to appropriately credit the source material, any unintentional oversight or omission does not constitute a copyright infringement. All trademarks, logos, and images mentioned are the property of their respective owners. If you believe that any content used in this article infringes upon your copyright, please contact us immediately for review and prompt action.
This article is intended for informational and educational purposes only and does not infringe on the rights of the copyright owners. If any copyrighted material has been used without proper credit or in violation of copyright laws, it is unintentional and we will rectify it promptly upon notification. Please note that the republishing, redistribution, or reproduction of part or all of the contents in any form is prohibited without express written permission from the author and website owner. For permissions or further inquiries, please contact us.