The Action ClassThe Action can be very simple or very complicated. For example, when a user clicks on the create new account button, control is passed to NewAccountAction (shown in Listing 8.1). Listing 8.1 NewAccountAction.javapackage stocktrack.struts.action; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.*; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionForm; import org.apache.struts.action.Action; /** * stocktrack.struts.action.IndexAction class. * this class used by Struts Framework process the * stocktrack.struts.form.BlankForm form. * - method invoked by HTTP request is perform(....) * - form name is blankForm * - input page is /home.jsp * - scope name is request * - path for this action is /newaccount * * struts-config declaration: * <action name="blankForm" * path="/newaccount" * type="stocktrack.struts.action.NewAccountAction" * input="/home.jsp" * scope="request" * validate="true" > * <!-- yours forwards --> * </action> * * @see org.apache.struts.action.Action org.apache.struts.action.Action * Generated by StrutsWizard. */ public class NewAccountAction extends org.apache.struts.action.Action { public ActionForward perform(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { return mapping.findForward("newUser"); } } As you can see, all the perform() method of this class does is to immediately tell Struts to go to the page identified by the tag newUser in the configuration file.
This type of ultra -simple Action is the exception, however. Most Action classes do a significant piece of work. For example, Listing 8.2 shows the Action that implements new user creation. Listing 8.2 NewUserAction.javapackage stocktrack.struts.action; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.*; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionError; import org.apache.struts.action.Action; import stocktrack.torque.*; import stocktrack.struts.form.NewUserForm; /** * stocktrack.struts.action.NewUserAction class. * this class used by Struts Framework process the * stocktrack.struts.form.NewUserForm form. * - method invoked by HTTP request is perform(....) * - form name is newUserForm * - input page is newUser.jsp * - scope name is request * - path for this action is /newuser * * struts-config declaration: * <action name="newUserForm" * path="/newuser" * type="stocktrack.struts.action.NewUserAction" * input="newUser.jsp" * scope="request" * validate="true" > * <!-- yours forwards --> * </action> * * @see org.apache.struts.action.Action org.apache.struts.action.Action * Generated by StrutsWizard. */ public class NewUserAction extends org.apache.struts.action.Action { public ActionForward perform(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { NewUserForm uf = (NewUserForm) form; try { User u = UserPeer.findUserByUsername(uf.getUsername()); if (u != null) { ActionErrors errors = new ActionErrors(); errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("stocktrack.newuser.duplicate.user")); this.saveErrors(request, errors); return mapping.getInputForward(); } u = new User(); u.setUserEmailAddress(uf.getEmail()); u.setUserFirstName(uf.getFirstName()); u.setUserLastName(uf.getLastName()); u.setUserPassword(uf.getPassword()); u.setUserUsername(uf.getUsername()); Address a = new Address(); a.setAddressStreet1(uf.getStreetAddress1()); a.setAddressStreet2(uf.getStreetAddress2()); a.setAddressCity(uf.getCity()); a.setAddressState(uf.getState()); a.setAddressPostalCode(uf.getPostalCode()); a.setAddressWorkPhone(uf.getWorkPhone()); a.setAddressWorkExt(uf.getWorkExt()); a.setAddressHomePhone(uf.getHomePhone()); a.save(); u.setAddress(a); u.save(); request.getSession().setAttribute(stocktrack.Constants.VALIDATED_USER, u); return mapping.findForward("home"); } catch (Exception ex) { ex.printStackTrace(); return mapping.findForward("error"); } } } The first thing most Action s do in their perform() method is to cast the generic ActionForm argument to the actual class of the form that is being submitted to it. This allows the method to gain access to the properties of the form. Because you don't want the user to create an account if someone is already using that username, the next thing the method does is to call the model for the user to ask whether there is already such an account. If there is, the method creates a new ActionError s and ActionError , just as an ActionForm validate() method would. Because you're no longer in the validate() method, you need to use the saveErrors call to add the errors, so that the view will see them correctly when it redisplays the form. Finally, the code must redirect back to the form. Because a single Action could be used by several forms, the getInputForward call makes sure that control is returned to the form that actually did the submit. Assuming that there's no username conflict, the model is used to create a User and Address . If things go well, the Action then returns an ActionForward that causes the Controller to return to the home page. If an exception is thrown for some reason, such as a database error, the Controller is directed to go to a general error page. |