Struts and XDoclet

Now that you've seen how to create a simple Struts Web app, let's look at what needs to be done to reduce the amount of work in developing a Struts app. Let's begin with the bean we used to hold the username and password information (from the first code listing of this chapter). This bean is defined in the struts-config.xml file using the following code:

 <form-bean type="RegisterForm"/>

You might be thinking, why use XDoclet to define the bean in the config file when it is just as simple as the declaration as above? The reasons are numerous, including making typos, remembering to remove the declaration if the bean is removed from the system, as well as others. The idea of XDoclet is simplity and not duplicating anything that shouldn't be duplicated. This means we can use an XDoclet tag to generate the <form-beans> element automatically. The tag is called @struts.form and is shown here:

 * @struts.form 
import org.apache.struts.validator.ValidatorForm*;
public class RegisterForm extends ValidatorForm {
 protected String username;
 protected String password;
 protected String password2;
 public String getUsername() { return this.username; }
 public String getPassword() { return this.password; }
 public String getPassword2() { return this.password2; }
 * @struts.validator type="required"
 public void setUsername(String username) { this.username = username; };
 * @struts.validator type="required"
 public void setPassword(String password) { this.password = password; };
 * @struts.validator type="required"
 public void setPassword2(String password) { this.password2 = password; };

As you can see, the @struts.form tag is quite simple. Just assign the name attribute to the name of the bean being used in the app. Also notice that we changed the parent class from ActionForm to ValidatorForm. In the past, setting up a form for validation was a very time-consuming process. This isn't the case anymore with XDoclet. Just extend ValidatorForm and set a @struts.validator tag on the setter functions, as shown above. Now we don't need to worry about the <form-beans> element. Another important part of the struct configuration file is the mapping necessary for the forms as well as the success/failure pages. The tags necessary are @struts.action and @struts.action-forward, and they are shown here:

 * @struts.action path="/struts"
 * scope="request"
 * input="/logon.jsp"
 * validate="true"
 * @struts.action-forward * path= "/WEB-INF/success.jsp"
 * @struts.action-forward * path= "/WEB-INF/failure.jsp"
import org.apache.struts.action.*;
import javax.servlet.http.*;
public class RegisterAction extends Action {
 public ActionForward perform(
ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
 RegisterForm rf = (RegisterForm) form;
 String username = rf.getUsername();
 String password = rf.getPassword();
 String password2 = rf.getPassword2();
 if (password.equals(password2)) {
 try {
 return mapping.findForward("success");
 } catch(Exception e) {
 return mapping.findForward("failure");
 return mapping.findForward("failure");

In this code we have provided three mappings. The first is called the action mapping, and it handles the mapping from the RegisterForm to the RegisterAction class needed when the user enters her username and passwords. XDoclet is able to obtain the class when the RegisterForm name is used based on where the @struts.action tag is located. We also defined the two findForward strings, failure and success. These values are mapped to the appropriate .jsp files. At this point in the development, we have eliminated the need to produce the validation configuration as well as the struts configuration file. Of course, we will need an appropriate Ant task to do the actual XDoclet work. The Ant task follows:

 <target depends="init">
 <mkdir dir="${build.dir}/web/WEB-INF"/>
 <path refid="xdoclet.classpath"/>
 <path refid="web.compile.classpath"/>
 <webdoclet destdir="${build.dir}/web/WEB-INF"
 <fileset dir="src/web"/>
 <deploymentdescriptor validatexml="true"
 <strutsconfigxml validatexml="true"

The Ant task for <webdoclet> looks just like the other ones we've used in the past except we've added two additional subtasks: <strutsconfigxml> and <strutsvalidationxml>. These two subtasks do all of the work in generating the necessary support files for our app.