Apache Struts to Spring MVC Blueprint
Replace an end-of-life Apache Struts web tier with Spring MVC, converting actions to controllers and ActionForms to validated command objects. Spring Security and CSRF protection close the OWASP gaps that legacy Struts leaves open.
What and Why
Apache Struts, especially Struts 1 which reached end of life in 2013, carries well-known critical vulnerabilities and an action-form programming model that is verbose and hard to maintain. High-profile breaches have traced directly to unpatched Struts. This blueprint replaces Struts with Spring MVC, giving the web tier active support, a cleaner annotation-driven controller model, and modern security defaults. Spring MVC is the web framework within the Spring ecosystem that maps HTTP requests to controller methods and binds request data to typed objects.
Phases
Assessment. Inventory Struts actions, form beans, the struts-config.xml mappings, validation rules, and the Tiles layouts or JSP views in use. Record the exact Struts version and cross-reference its components against published CVEs so the most dangerous, internet-facing screens are prioritized first.
Action mapping. Translate each Struts Action class to a Spring @Controller method. Map the URL patterns from struts-config.xml to @RequestMapping (or @GetMapping/@PostMapping) annotations, and convert ActionForms into Spring command objects annotated with Bean Validation constraints, which replaces Struts' separate validation framework with standard, declarative validation.
View migration. Keep JSPs where practical but replace Struts custom tags with JSTL or Spring form tags. Migrate Tiles composite layouts to Spring's layout support or, for new screens, to a modern server-side template engine such as Thymeleaf, which has better tooling and auto-escaping.
Security hardening. Replace Struts interceptors with Spring Security filters, enable CSRF protection (which Spring Security provides by default), and remediate any OWASP Top 10 issues the old framework exposed. Add static application security testing (SAST) to the CI pipeline so new vulnerabilities are caught automatically.
Cutover. Use the strangler fig pattern to route URLs to the new Spring controllers one screen at a time behind a front controller, validating behavior in production before retiring each Struts action and its configuration.
Key Risks and Mitigations
- Security vulnerabilities: Escaping Struts CVEs is the whole point, so migrate internet-facing actions first and validate the result with SAST and dependency scanning before declaring a screen done.
- Downtime: Migrate screen by screen rather than swapping the framework wholesale, keeping the old action available until the new one is proven.
- Skills gap: Developers must learn Spring MVC data binding and Spring Security configuration. Pair on the first few controllers so the patterns are well understood before scaling out.
Recommended Tooling
Spring Boot with Spring MVC and Spring Security, Thymeleaf for new views, Docker for packaging into containers, and a SAST scanner wired into CI to enforce the security baseline.
Success Metrics
Track lead time and deployment frequency for web-tier changes, which improve once the modern framework is in place, and MTTR for security incidents, which should drop sharply once the unmaintained framework is gone.
Prerequisites
Full source for all actions and views, a record of the current URL contracts so they are preserved, a test suite or manual test scripts per screen, and a security baseline to measure improvement against.
Sequencing and Rollback
Sequence screens by exposure and risk: migrate the internet-facing actions with known CVE exposure first, then internal screens. Keep the Struts front controller able to serve any unmigrated action so rollback of a single screen is a routing toggle. Maintain visual and behavioral parity tests per screen so a regression is caught before users see it. Because no database schema changes, every screen migration is independently reversible, which lets the team move quickly without risking a hard-to-undo cutover. Ensure a dependency-scanning step is in place so newly introduced libraries are checked against known CVEs, closing the loop that the original Struts exposure left open and keeping the hardened state from regressing over time.