Article
Complete the MVC Puzzle with Struts
Struts in Action
Having looked at all the pieces that make up a Struts application, we can now assemble a simple application that performs the same job as the original application in this article, that is, to log a user in and display a welcome message.
First, we’ll examine our View. In this application the view is made of 2 simple JSPs, the first of which allows users to input their username and password, and is shown below:
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<html:html>
<head></head>
<body bgcolor="white">
<html:errors/>
<html:form action="/ProcessLogin">
<table border="0" width="100%">
<tr>
<td>
Username:
</td>
<td>
<html:text property="username"/>
</td>
</tr>
<tr>
<td>
Password:
</td>
<td>
<html:password property="password"/>
</td>
</tr>
<tr>
<td>
<html:submit/>
</td>
<td>
</td>
</tr>
</table>
</html:form>
</body>
</html:html>
This is very similar to the page we examined in the earlier section discussing views. It simply defines a form using the Struts <html> tags, and associates this with an Action defined in the configuration named /ProcessLogin. When the form is submitted, the appropriate ActionForm will be created and the appropriate action will be called to process the input. We can also see that the <html:errors> tag is used. This will automatically display any validation errors that are indicated by the form (see below).
The second JSP in our view is yet simpler. The code is shown below:
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<html:html>
<h1>Welcome <bean:write name="loginForm" property="username" /></h1>
</html:html>
This page simply displays a property (username) of an ActionForm bean named loginForm. This uses the Struts <bean> tag library.
Next, we’ll look at our Controller layer. This is implemented as an ActionForm class, and one Action class. The ActionForm class is very simple, and maps to our model (in this case, a simple JavaBean object.)
package com.samjdalton.struts;
import org.apache.struts.action.ActionForm;
public class LoginForm extends ActionForm {
private LoginBean bean;
public LoginForm() {
this.bean=new LoginBean();
}
public LoginForm(LoginBean bean) {
this.bean = bean;
}
public void setUsername(String username) {
bean.setUsername(username);
}
public String getUsername() {
return bean.getUsername();
}
public void setPassword(String password) {
bean.setPassword(password);
}
public String getPassword() {
return bean.getPassword();
}
}
Our action class uses this ActionForm to get information from the view, and to update the model. The Action is shown below:
package com.samjdalton.struts;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
public class LoginAction extends Action {
public ActionForward execute(ActionMapping actionMapping, ActionForm actionForm, javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
// check the username
LoginForm form = (LoginForm) actionForm;
if (form.getUsername().equalsIgnoreCase("sam") && form.getPassword().equals("password")) {
// we are in
return actionMapping.findForward("success");
} else {
// not allowed
return actionMapping.findForward("failure");
}
}
public ActionErrors validate(ActionMapping actionMapping
HttpServletRequest httpServletRequest) {
ActionErrors errors = new ActionErrors();
if ( getUsername() == null || getUsername().length() < 1 ) {
errors.add("name",new ActionError("error.name.required"));
}
if ( getPassword() == null || getPassword().length() < 1 ) {
errors.add("pw",new ActionError("error.pw.required"));
}
return errors;
}
As you can see, this action checks that the user has entered the username, sam and the password, password. If this is the case, then the Action indicates that the next view to show is represented by the ActionMapping success; otherwise the failure ActionMapping should be shown.
The ActionForm class also contains a method called validate. This method allows us to perform some basic validation on the contents of the form, and notify the user of any errors (missing fields etc). In our case, the validate method checks to see that the username and password are both filled in. If they are not, then the user is sent one or both error messages. These messages are contained in a resource file (to aid internationalisation), which is defined in the configuration file, as we’ll shortly see.