Let’s design some JSPs and an action class to show how it works. We are creating a two JSP pages—
add_user.jsp and user.jsp. The action class created here is UserAction.
Here’s the code, given Listing 3.17 for UserAction action class (you can find the UserAction.java file in Code\Chapter 3\Struts2Action\WEB-INF\src\com\kogent\action folder in CD):
Listing 3.17: UserAction.java
package com.kogent.action;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import org.apache.struts2.interceptor.ApplicationAware;
import com.kogent.User;
import com.opensymphony.xwork2.ActionSupport;
public class UserAction extends ActionSupport implements ApplicationAware{
String username;
String password;
String city;
String email;
String type;
Map application;
public void setApplication(Map application) { this.application=application;
}
public String getUsername() {
return username;
}
public void setUsername(String username) { this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) { this.password = password;
}
public String getCity() {
return city;
}
public void setCity(String city) { this.city = city;
}
public String getEmail() {
return email;
}
public void setEmail(String email) { this.email = email;
}
public String getType() {
return type;
}
public void setType(String type) { this.type = type;
}
public String execute() throws Exception {
ArrayList users=(ArrayList)application.get("users");
if(users==null){
users=new ArrayList();
}
if(getUser(username)==null){
users.add(buildUser());
application.put("users", users);
}else{
this.addActionError("User Name is in use.");
return ERROR;
user.setUsername(username);
user.setPassword(password);
user.setCity(city);
user.setEmail(email);
user.setType(type);
return user;
}
public User getUser(String username){
User user=new User();
boolean found=false;
ArrayList users=(ArrayList)application.get("users");
if(users!=null){
Iterator it=users.iterator();
while(it.hasNext()){
user=(User)it.next();
if(username.equals(user.getUsername())){
found=true;
break;
}
public void validate() {
if ( (username == null ) || (username.length() == 0) ) {
this.addFieldError("username", getText("app.username.blank"));
}
if ( (password == null ) || (password.length() == 0) ) {
this.addFieldError("password", getText("app.password.blank"));
}
if ( (email == null ) || (email.length() == 0) ) {
this.addFieldError("email", getText("app.email.blank"));
}
} }
This action class extends com.opensymphony.xwork2.ActionSupport class and implements org.apache.struts2.interceptor.ApplicationAware interface. The ActionSupport class itself implements different interfaces, like Action, LocaleProvider, TextProvider, Validateable, ValidationAware, etc. and provides default implementations for the methods from these interfaces, which we can use in our action class.
The extending of ActionSupport class enables you to use methods, like addFieldError(), addActionError(), getText(), etc. The implementation of ApplicationAware interface brings an Application Map object into role, which can be managed in the action to store attributes in application scope. The objects stored in Application Map is available in the whole application.
In UserAction action class, the execute() method has the logic to add a new user into an ArrayList, which is maintained in application scope. The getUser() method searches for the user with the given username and returns an object of User class. This class is a simple JavaBean which is used to group single user information. The ArrayList ‘users’ in application scope basically contains the objects of User class.
Here’s the code, given in Listing 3.18 for User class (you can find User.java file in Code\Chapter 3\Struts2Action\WEB-INF\src\com\kogent folder in CD):
Listing 3.18: User.java
package com.kogent;
public class User {
String username;
String password;
String city;
String email;
String type;
public String getUsername() {
return username;
}
public void setUsername(String username) { this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) { this.password = password;
}
public String getCity() {
return city;
}
public void setCity(String city) { this.city = city;
}
public String getEmail() {
return email;
}
public void setEmail(String email) { this.email = email;
}
public String getType() {
return type;
}
public void setType(String type) { this.type = type;
} }
Another method of UserAction action class is buildUser() which returns an object of User class to be added into the ArrayList after populating it with the values of corresponding input properties. The execute() method makes sure that no two User objects with the same username are added into the application scoped ArrayList.
Now add the following action mapping, shown in Listing 3.19, for this new action class in your struts.xml file.
Listing 3.19: struts.xml with action mapping for UserAction action.
<struts>
<include file="struts-default.xml"/>
<package name="my-default" extends="struts-default">
<action name="hello" . . . .>
. . . . </action>
<action name="adduser" class="com.kogent.action.UserAction" >
<result name="input">add_user.jsp</result>
<result name="error">add_user.jsp</result>
<result name="success">user.jsp</result>
</action>
</package>
</struts>
The two JSP files configured as input, success, and error results are created now. The add_user.jsp page provides a form with five input fields having names matching with the input properties defined in UserAction class.
Here’s the code, given in Listing 3.20, for add_user.jsp page (you can find add_user.jsp file in Code\Chapter 3\Struts2Action folder in CD):
Listing 3.20: add_user.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<html>
<head>
<title><s:text name="app.title" />
</title>
<link rel="stylesheet" href="mystyle.css" type="text/css" />
</head>
<body>
<center>
Adding User!
<br><br>
<table bgcolor="#f0edd9">
<tr><td>
<s:actionerror />
<s:form action="adduser">
<s:textfield name="username" label="User Name" />
<s:password name="password" label="Password" size="15" />
<s:textfield name="city" label="City" />
<s:textfield name="email" label="E-Mail" />
<s:select label="Type" name="type" headerKey="- - -"
headerValue="Select Type"
list="#{'Admin':'Admin', 'Client':'Client'}" />
<s:submit value="Add User" />
</s:form>
</td></tr>
</table>
<br>| <s:a href="index.jsp">Back</s:a> | </center>
</body>
</html>
The action attribute of <s:form/> used in this JSP page has the value adduser and will use UserAction for the processing of data entered into this form. We can click on “Add User” hyperlink, created in index.jsp and shown in Figure 3.2, to get the add_user.jsp page. The output of add_user.jsp page is shown in Figure 3.4.
Figure 3.4: The add_user.jsp page showing form to add new user.
Enter some data into the fields and click on ‘Add User’ button to add a new user. If the username entered is unique, a new User object is added into an ArrayList, which is added into application scope. The successful addition of new user brings user.jsp page that lists all the users added.
Here’s the code, given in Listing 3.21, for user.jsp page (you can find user.jsp file in Code\Chapter 3\Struts2Action folder in CD):
Listing 3.21: user.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="/struts-tags" prefix="s" %>
<html>
<head>
<title><s:text name="app.title"/></title>
<link rel="stylesheet" href="mystyle.css" type="text/css" />
</head>
<body>
<s:set name="users" value="#application.users"/>
<table cellspacing="5" cellpadding="2" width="600">
<tr bgcolor="#f0edd9">
<td>User Name</td>
<td>Password</td>
<td>City</td>
<td>Email</td>
<td>Type</td>
<td colspan="2"> </td>
</tr>
<s:iterator id="user" value="users">
<tr>
<td><s:property value="username"/></td>
<td><s:property value="password"/></td>
<td><s:property value="city"/></td>
<td><s:property value="email"/></td>
<td><s:property value="type"/></td>
<td>
<s:url id="url" action="getuser">
<s:param name="username"><s:property value="username"/></s:param>
</s:url>
<s:a href="%{url}">Edit</s:a>
</td>
<td>
<s:url id="url" action="delete">
<s:param name="username"><s:property value="username"/></s:param>
</s:url>
<s:a href="%{url}">Delete</s:a>
</td>
</tr>
</s:iterator>
</table>
<br>| <s:a href="index.jsp">Home</s:a> |
<s:a href="add_user.jsp">Add More</s:a> |
</body>
</html>
Listing 3.21 uses the <s:iterator/> tag to iterate over the ArrayList and displays values of all fields set for each user. The output of user.jsp page is shown in Figure 3.5.
Figure 3.5: The user.jsp showing a list of users added.
You can see two hyperlinks rendered in front of each user record, i.e. ‘Edit’ and ‘Delete’. These hyperlinks are not functional yet. It needs creation of some other action class and JPS pages to make them work.