<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.
Refer to this structure in case you did something wrong. 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.
Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.