<dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-convention-plugin</artifactId> <version>2.3.20</version> </dependency>You can see that the latest version of Struts 2 framework is used, 2.3.20. To understand more about Struts 2 annotations, refer to Struts2 Beginner Tutorial with Annotations.
/** * Copyright (C) CodeJava.net from 2012 To Present * All rights reserved. */ package net.codejava.struts; public class User { private String username; private String email; private String password; 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; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Spring and Struts Integration Demo</title> </head> <body> <div align="center"> <h1>Spring and Struts Integration Demo</h1> <h2>Users Login</h2> <s:form action="doLogin" method="post"> <s:textfield label="Username" name="user.username" /> <s:password label="Password" name="user.password" /> <s:submit value="Login" /> </s:form> </div> </body> </html>Note that the URL in the form’s action attribute is: /doLogin. We’ll configure an appropriate action class to handle this URL later.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Login Success</title> </head> <body> <div align="center"> <h1>Welcome to CodeJava.net</h1> </div> </body> </html>Code of the Error page:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Login Error</title> </head> <body> <div align="center"> <h1>Error login. Wrong username/password</h1> </div> </body> </html>You will see how to configure redirection to these pages in the next section about Struts action classes.
/** * Copyright (C) CodeJava.net from 2012 To Present * All rights reserved. */ package net.codejava.struts; public class UserDAO { public boolean checkLogin(User user) { return user.getUsername().equals("admin") && user.getPassword().equals("nimda"); } }You will see how to auto-wire this business class into a Struts action class in the next section.
/** * Copyright (C) CodeJava.net from 2012 To Present * All rights reserved. */ package net.codejava.struts; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Result; import org.apache.struts2.convention.annotation.ResultPath; import com.opensymphony.xwork2.ActionSupport; @Action("login") @ResultPath("/WEB-INF/views") @Result(name = "success", location = "LoginForm.jsp") public class ViewLoginAction extends ActionSupport { // this is intentionally empty }And the second action class (DoLoginAction.java) is for handling submission from the login form (URL /doLogin). Here’s its code:
/** * Copyright (C) CodeJava.net from 2012 To Present * All rights reserved. */ package net.codejava.struts; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Result; import org.apache.struts2.convention.annotation.ResultPath; import org.apache.struts2.convention.annotation.Results; import org.springframework.beans.factory.annotation.Autowired; import com.opensymphony.xwork2.ActionSupport; @Action("/doLogin") @ResultPath("/WEB-INF/views") @Results({ @Result(name = "success", location = "LoginSuccess.jsp"), @Result(name = "error", location = "LoginError.jsp") }) public class DoLoginAction extends ActionSupport { @Autowired private UserDAO userDAO; private User user; public void setUser(User user) { this.user = user; } public User getUser() { return user; } public String execute() { if (userDAO.checkLogin(user)) { return SUCCESS; } return ERROR; } }Note that the @Autowired annotation (from Spring) is used to let Spring automatically inject an instance of the UserDAO class into the instance of this action class:
@Autowired private UserDAO userDAO;You’ll see how to let Spring manage an instance of the UserDAO class in the next section.
/** * Copyright (C) CodeJava.net from 2012 To Present * All rights reserved. */ package net.codejava.struts.config; import java.util.EnumSet; import javax.servlet.DispatcherType; import javax.servlet.FilterRegistration; import javax.servlet.ServletContext; import javax.servlet.ServletException; import org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter; import org.springframework.web.WebApplicationInitializer; import org.springframework.web.context.ContextLoaderListener; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; public class WebAppInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext(); appContext.register(ApplicationContextConfig.class); ContextLoaderListener contextLoaderListener = new ContextLoaderListener(appContext); servletContext.addListener(contextLoaderListener); FilterRegistration.Dynamic filter = servletContext.addFilter( "StrutsDispatcher", new StrutsPrepareAndExecuteFilter()); filter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*"); } }You can see that the Spring framework is configured as a context listener:
AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext(); appContext.register(ApplicationContextConfig.class); ContextLoaderListener contextLoaderListener = new ContextLoaderListener(appContext); servletContext.addListener(contextLoaderListener);On start-up, Spring looks for configuration in the ApplicationContextConfig class which is described in the next section.And the Struts framework is configured as the primary dispatcher filter:
FilterRegistration.Dynamic filter = servletContext.addFilter( "StrutsDispatcher", new StrutsPrepareAndExecuteFilter()); filter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");This configuration allows Struts framework intercepts all requests coming through the application.For more information regarding how to bootstrap a framework programmatically in Java EE, see the tutorial: Bootstrapping a Spring Web MVC application programmatically.
/** * Copyright (C) CodeJava.net from 2012 To Present * All rights reserved. */ package net.codejava.struts.config; import net.codejava.struts.UserDAO; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan("net.codejava.struts") public class ApplicationContextConfig { @Bean(name = "userDAO") public UserDAO getUserDAO() { return new UserDAO(); } }Here, we declare only one bean instance for the UserDAO class, which is then injected into the Struts action class. That’s all for the code stuffs.
http://localhost:8080/Spring4Struts2IntegrationAnnotations/login
Then the login form appears. Enter username as ‘admin’ and password as ‘nimda’, and then hit Enter. You will see the success page; otherwise the error page gets displayed.Congratulations! You have done the second part of Spring and Struts integration series. You can now master the key concepts and techniques in implementing a Spring-Struts application.