The Action Class


The Action Class

The 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.java
 package 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.

NEVER USE REFERENCES TO JSP FILES

One of the strengths of Struts is that filenames are referenced in only one place: the struts-config.xml file. Everywhere else, pages are referenced by logical names that are mapped to the actual JSP. One big advantage of this is that if a file is renamed or moved to a different directory, only one file must be changed.

So, given this imperative, how do you do a simple page-to-page link? You've just seen the solution. You create a blank form (which can be reused for all the interpage transitions), and a small Action that simply dispatches to the page you want to go to.

Then, instead of saying <html:link HREF="page.jsp/"> , you say <html:link HREF="page.do"/> . If you've configured Struts to associate page with the blank form and new Action you've created, you'll be delivered to the page.

Another benefit of this approach is that if you decide in the future that you want to restrict access to this page, you've already got an Action set up to check the permissions.

If you don't need the full power of an Action , Struts will also enable you to map a .do URI directly to a JSP page by using the forward= directive in an action tag inside the struts-config.xml 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.java
 package 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.



Struts Kick Start
Struts Kick Start
ISBN: 0672324725
EAN: 2147483647
Year: 2002
Pages: 177

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net