Recipe2.8.Selectively Disabling Actions


Recipe 2.8. Selectively Disabling Actions

Problem

You want to disable an action using a custom property that can be set on the action element in your struts-config.xml file; forwarding any requests to the disabled action to an "under construction" page.

Solution

Create a custom ActionMapping extension (as shown in Example 2-16) that provides a boolean property indicating if the action is disabled or not.

Example 2-16. Custom ActionMapping
import org.apache.struts.action.ActionMapping; public class DisablingActionMapping extends ActionMapping {     private String disabled;     private boolean actionDisabled = false;          public String getDisabled( ) {         return disabled;     }     public void setDisabled(String disabled) {         this.disabled = disabled;         actionDisabled = new Boolean(disabled).booleanValue( );     }          public boolean isActionDisabled( ) {         return actionDisabled;     } }

This action mapping class can now be specified in the struts-config.xml file. You set the disabled property to TRue if an action is to be disabled:

<action-mappings type="com.oreilly.strutsckbk.DisablingActionMapping">   <!-- Edit mail subscription -->   <action    path="/editSubscription"              type="org.apache.struts.webapp.example.EditSubscriptionAction"         attribute="subscriptionForm"             scope="request"          validate="false">     <set-property property="disabled" value="true"/>     <forward name="failure"              path="/mainMenu.jsp"/>     <forward name="success"              path="/subscription.jsp"/>   </action>

Then create a custom RequestProcessor, such as the one shown in Example 2-17, that handles the DisablingActionMapping.

Example 2-17. Processing requests for disabled actions
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.RequestProcessor; public class CustomRequestProcessor extends RequestProcessor {          protected ActionForward processActionPerform(HttpServletRequest request,             HttpServletResponse response, Action action,ActionForm form,              ActionMapping mapping) throws IOException, ServletException {         ActionForward forward = null;         if (!(mapping instanceof DisablingActionMapping)) {             forward = super.processActionPerform( request, response,                                                      action, form, mapping);         }         else {             DisablingActionMapping customMapping =                    (DisablingActionMapping) mapping;             if (customMapping.isActionDisabled( )) {                 forward = customMapping.findForward("underConstruction");             }             else {                 forward = super.processActionPerform( request, response,                                                          action, form, mapping);             }         }         return forward;     } }

Discussion

Struts supports the capability of providing custom properties to an Action tHRough two primary mechanisms. First, every Struts action can be passed through a general purpose parameter value:

<action    path="/editRegistration"            type="org.apache.struts.webapp.example.EditRegistrationAction"       attribute="registrationForm"           scope="request"        validate="false"        parameter="disabled">   <forward name="success" path="/registration.jsp"/> </action>

Second, in the Action implementation, the value of the parameter can be accessed with this code:

String parameterValue = mapping.getParameter(  );

However, some of the Struts-provided Action subclasses, such as the DispatchAction, are predicated on the use of the parameter attribute. Since you can specify only one parameter attribute, you will not be able to use the parameter for a custom value if you are using one of these pre-built Action subclasses.

For complete extensibility, you can extend the ActionMapping class, optionally providing accessor and mutator methods for custom properties of your own choosing:

package com.oreilly.strutsckbk; import org.apache.struts.ActionMapping public class MyCustomActionMapping extends ActionMapping {     private String customValue;     public String getCustomValue( ) { return customValue; }     public String setCustomValue(String s) { customValue = s; } }

You can reference this custom extension in the struts-config.xml file. If the custom action mapping should be used globally for all actions, set the type attribute of the action-mappings element to the fully qualified class name of the custom extension:

<action-mappings type="com.oreilly.strutsckbk.MyCustomActionMapping">

Otherwise, set the className attribute of the action element for which the custom action mapping is needed. In either case, the set-property element can be used to set values for JavaBean properties in the custom extension for a specific action element:

<action    path="/someAction"            type="com.oreilly.strutsckbk.SomeAction"       className="com.oreilly.strutsckbk.MyCustomActionMapping">   <set-property property="customValue" value="some value"/> </action>

To make your custom mapping as robust as possible, accept only a String value in the setter method for a set-property. You can perform any necessary data conversion in the class itself, setting the value to acceptable default if an unexpected value is passed.


The Solution uses a custom RequestProcessor for handling the disabled property of the custom ActionMapping. If you were using a custom ActionMapping for only specific actions, you could access the custom ActionMapping property directly in the Action.execute() method:

boolean disabled = ((DisablingActionMapping) mapping).isActionDisabled(  ); if (disabled) return mapping.findForward("underConstruction");

See Also

You could use an authorization servlet filter to solve this problem. Recipe 11.8 shows an approach that could be applied to this problem.



    Jakarta Struts Cookbook
    Jakarta Struts Cookbook
    ISBN: 059600771X
    EAN: 2147483647
    Year: 2005
    Pages: 200

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