Controlling the validation


The default mechanism in Struts to skip validations when a button is pressed is by using < html:cancel > in the JSP. Behind the scenes, this tag creates a button with a name ‚ org.apache.struts.taglib.html.CANCEL . When the page is finally submitted, one of the first things RequestProcessor does is to check if the request has a parameter with the name org.apache.struts.taglib.html.CANCEL . If so, the validation is cancelled and the processing continues. While this may be acceptable for grey buttons (even those pages with multiple buttons), image buttons cannot be named as org.apache.struts.taglib.html.CANCEL due to their peculiar behavior. When images are used for form submission, the browsers do not submit the name and value, but the X and Y coordinates of the image. This is in accordance with the W3C specification. Even though an image corresponding to Cancel was pressed, the RequestProcessor is oblivious to this fact. It innocently requests the page validation and the end user is only but surprised to see the validation pop up! This is an area where some minor customization goes a long way. Let us start by customizing the action mapping in the struts-config.xml. Listing 10.4 shows the new addition in bold.

Listing 10.4: struts-config.xml with global custom action mapping
 <action-mappings type="mybank.struts.MyActionMapping">     <action   path="/submitCustomerForm"               type="mybank.app1.CustomerAction"               name="CustomerForm"               scope="request"  validate="false"  input="CustomerDetails.jsp">       <set-property property="buttons"                   value="nextButton,saveButton,cancelButton" />   <  set-property property="validationFlags"   value="false,true,false" /  >       <forward name="page2"  path="Page2.jsp"  />       <forward name="success"  path="success.jsp"  />       <forward name="success"  path="cancel.jsp"  />     </action>     </action-mappings> 
 

In addition to the existing < set-property > elements, a new < set-property > is added for a property called validationFlags . This is a comma-separated list of true and false telling Struts if validation needs to be performed when corresponding buttons (also comma-separated values) are selected on the browser. The validationFlags in the Listing are interpreted as: ‚“When next and cancel buttons are selected, no validation is necessary. When save button is selected, validation is required ‚½. In addition another interesting change you will find in Listing 10.4 is that the validation is turned off by setting validate=false . With this setting, the validation in RequestProcessor is completely turned off for all buttons. The validation will be explicitly invoked in the base Action ‚ s execute() method. Listing 10.5 shows the execute() method. The changes are shown in bold.

Listing 10.5: execute() method for controlling validation
 Public MybankBaseAction extends Action {   public ActionForward execute(ActionMapping mapping,             ActionForm form, HttpServletRequest request,             HttpServletResponse response) throws Exception {           ...     MybankBaseForm myForm = (MybankBaseForm) form;        ...     MyActionMapping myMapping = (MyActionMapping) mapping;     String selectedButton =                 getSelectedButton(myForm, myMapping);  boolean validationReqd =   myMapping.isValidationRequired(buttons[i]);   if (validationReqd) {   ActionErrors errors =   myForm.validate(myMapping, request);   if (errors != null  &&  ! errors.isEmpty()) {   saveErrors(request, errors);   return myMapping.getInput();   }   }  preprocess(myMapping, myForm, request, response);     ActionForward forward =          process(myMapping, myForm, request, response);   postprocess(myMapping, myForm, request, response);       ...           return forward;   } } 
 

The new validationFlags setting requires some minor code changes to the in MyBankBaseAction . The changes involve explicitly running the form validation and saving the ActionErrors. The key logic deciding if the validation is required for the selected button is in MyActionMapping class in isValidationRequired() method. The method requires the selected button name as an argument. A sample implementation for the isValidationRequired() method is as follows :

 public boolean isValidationRequired(String selectedButton) {   String validationStr = validationFlagMap.get(selectedButton);   return Boolean.valueOf(validationStr); } 

The above method uses the selected button name to lookup a HashMap named validationFlagMap . As you know, the JavaBeans properties ‚ buttons and validationFlags were provided as comma separated values. Parsing through the comma separated values at runtime for every user is a sheer waste of time and resources. Hence the comma-separated values are parsed in their corresponding setters to create a HashMap with the button name as the key. This ensures a fast retrieval of the values.

A sample implementation of the setters and the resolve() method is shown below:

 public void setButtons(String buttonNames) {   this.buttons = buttonNames;   resolve(); } public void setValidationFlags(String flags) {   this.validationFlags = flags;   resolve(); } public void resolve() {   if (buttons != null && validationFlags != null) {     validationFlagMap = new HashMap();     StringTokenizer stButtons = new StringTokenizer(buttons ",");     StringTokenizer stFlags =                       new StringTokenizer(validationFlags, ",");     while (stButtons.hasMoreTokens()) {       String buttonName = stbuttons.nextToken();       String flagValue = stFlags.nextToken();       validationFlagMap.put(buttonName, flagValue);     }       } } 

As seen above, every setter invokes the resolve() method. When the final setter is invoked, all the attributes are non-null and the if block in resolve() is entered. At this point every instance variable is guaranteed to be set by the Struts start up process. The resolve() method creates a StringTokenizer and parses the comma-delimited values to create a HashMap with button name as the key and the validation flag as the value. This HashMap thus created is utilized at runtime for a faster retrieval of flag values in the isValidationRequired() method.




Struts Survival Guide. Basics to Best Practices
Struts Survival Guide: Basics to Best Practices (J2ee Survival Series)
ISBN: 0974848808
EAN: 2147483647
Year: 2004
Pages: 96

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