To edit the user record, shown in Figure 3.6, we need to click over the ‘Edit’ button. But, before that, we have to decide which action is going to handle this form. The form is similar to what is prepared for adding a new user; hence we need the same set of input properties to be set as that of UserAction action class. Similarly, the validation logic for these fields will be same as what is implemented in the validate() method of UserAction. So, when all these things are similar and can be reused, there is no need for creating a new action class here.
Struts 2 allows configuration of any method having signature String methodName() to be configured and invoked, which can work similar to the execute() method of action class.
Add a new method into your existing UserAction class. This method contains the logic to edit the users. The logic is to replace the existing User object in the ArrayList with the new User object created with new data.
Here’s the code, given in Listing 3.24, for edit() method:
Listing 3.24: edit() method of UserAction.java
public class UserAction extends ActionSupport implements ApplicationAware{
String username;
public void setApplication(Map application) { this.application=application;
}
//Setter and getter methods..
. . .
. . .
public String execute() throws Exception { . . .
return SUCCESS;
}
//New method added.
public String edit() throws Exception{
ArrayList users=(ArrayList)application.get("users");
User user=null;
int index=0;
Iterator it=users.iterator();
while(it.hasNext()){
User newuser=buildUser();
users.set(index, newuser);
application.put("users", users);
return SUCCESS;
}
public User buildUser(){
. . . . }
public User getUser(String username){
. . . . . . }
public void validate() { . . . .
. . . . } }
Recompile the UserAction action class and get the newly complied class file in WEB-INF\classes\com\kogent\action folder. Look at the action attribute of the <s:form/> tag used in edit_user.jsp page, which is set with the value ‘edit’. Add a new action mapping with the name ‘edit’, which invokes this new edit() method of UserAciton class having the logic to edit the user information. This is done by providing a method parameter in the action mapping as shown here:
<action name="edit" class="com.kogent.action.UserAction" method="edit" >
<result name="input">edit_user.jsp</result>
<result name="success">user.jsp</result>
</action>
Now, we can click on the ‘Edit’ button, shown in Figure 3.6, to use the edit() method of UserAction class. The edit() method updates the ArrayList and return from this method consequently shows you user.jsp page displaying updated data. Similarly, we can add one more method to delete the user information. The logic embedded in this method is just to remove the matching User object from the ArrayList.
Here’s the new method deleteUser(), given in Listing 3.25, added into UserAction.java.
Recompile the action after adding the new method.
Listing 3.25: deleteUser() method of UserAction.java
public String deleteUser() throws Exception{
ArrayList users=(ArrayList)application.get("users");
User user=null;
int index=0;
Iterator it=users.iterator();
while(it.hasNext()){
users.remove(index);
application.put("users", users);
return SUCCESS;
}
Consider the ‘Delete’ hyperlink shown in Figure 3.5, and observe the following code which creates this hyperlink:
<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>
Now provide a new action mapping to match with this action request, i.e. delete.action. The new action mapping to be added in struts.xml is shown here:
<action name="delete" class="com.kogent.action.UserAction" method="deleteUser" >
<interceptor-ref name="basicStack"/>
<result name="input">edit_user.jsp</result>
<result name="success">user.jsp</result>
</action>
The mapping provided here will invoke the deleteUser() method of the UserAciton action class, instead of executing its execute() method, as the method configured here is deleteUser. However, we do not want to execute the validate() method, as this time only the username is being passed as request parameter to the action. The validate() method of UserAciton would have certainly been executed if we would have used defaultStack as Interceptor stack here (all actions configured here uses the default Interceptor stack defaultStack).
The reason behind this concept is that the defaultStack Interceptor stack includes DefaultWorkflowInterceptor Interceptor, which basicStack does not. This Interceptor is responsible for invoking the validate() method before the real business logic method is invoked.
Now, we are ready to delete the existing users from the ArrayList. See the ‘Edit’ and ‘Delete’ options provided in Figure 3.5.
Creating LoginAction with ApplicaitonAware and SessionAware Interface
We already have created some actions in this application, which implements ApplicationAware and ServletRequestAware interfaces. Here, once again, we are creating a new action class which implements both ApplicaitonAware and SesstionAware interface. The implementation of SessionAware interface enables this action to handle a Session Map which stores objects in session scope. In this way, we become capable of handling session and session attributes.
We are creating a class to authenticate the user for its username and password. The success result will be rendered only when such user exists. This sets the username as the session attribute after finding the valid login attempt.
Here’s the code, given in Listing 3.26 for LoginAction action class (you can find LoginAcion.java file in Code\Chapter 3\Struts2Action\WEB-INF\src\com\kogent\action folder in CD):
Listing 3.26: LoginAcion.java
public class LoginAction extends ActionSupport implements ApplicationAware, SessionAware{
String username;
String password;
Map session;
Map application;
public void setSession(Map session) {
this.session=session;
}
public void setApplication(Map application) { this.application=application;
}
public String getPassword() {
return password;
}
public void setPassword(String password) { this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) { this.username = username;
}
public String execute() throws Exception { boolean found=false;
ArrayList users=(ArrayList)application.get("users");
if(users!=null){
Iterator it=users.iterator();
while(it.hasNext()){
User user=(User)it.next();
if(username.equals(user.getUsername()) &&
password.equals(user.getPassword())){
found=true;
session.put("user", username);
break;
}
this.addActionError("Invalid User Name or Password");
return ERROR;
} }
Let’s create a JSP page to provide input to this action class. This JSP page is a login page providing two input fields for username and password.
Here’s the code, given in Listing 3.27, for login.jsp page (you can find login.jsp file in Code\Chapter 3\Struts2Action folder in CD):
Listing 3.27: login.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>
Enter User Name and Password.<br><br>
<table bgcolor="#f0edd9">
<tr>
<td>
<s:actionerror />
<s:form action="login">
<s:textfield name="username" label="User Name"/>
<s:password name="password" label="Password" />
<s:submit value="Login"/>
</s:form>
</td>
</tr>
</table>
<br>| <s:a href="index.jsp">Home</s:a> | </center>
</body>
</html>
Click on the ‘Login’ hyperlink, shown in Figure 3.2, and created in Listing 3.13. This consequently shows you login.jsp page. The page looks like Figure 3.7.
Figure 3.7: The login.jsp page showing login form.
Add the following action mapping in the struts.xml file matching the action requested from this login form created here:
<action name="login" class="com.kogent.action.LoginAction" >
<result name="input">login.jsp</result>
<result name="error">login.jsp</result>
<result name="success">hello.jsp</result>
</action>
Now we can login by providing a valid set of username and password and clicking on the ‘Login’
button shown in Figure 3.7. The successful login brings you hello.jsp. However, the output of hello.jsp this time (Figure 3.8) is different from what is shown in Figure 3.3.
Figure 3.8: The hello.jsp showing username from session and a Logout option.
Similarly, we can see our index.jsp page after getting logged in. The welcome message on that page also changes. See the output of index.jsp shown in Figure 3.9.
Figure 3.9: The index.jsp page with different welcome message and Logout option.
Now the only option left here to be made functional is the Logout option. This again is achieved by creating a new action class.