ignore

Actions

Actions are the key artifacts in a Struts application because they are the primary home for service tier invocations as well as the application's presentation logic. In Strecks, the responsibility of a traditional Struts action is divided between two objects, an controller action and an action bean.

In the next sections we talk about the roles and responsibilities of controller actions and action beans. While it is less likely that you will need to write your own controller actions, you will probably find it useful to know a little bit about how they work when writing action beans. Once we've covered this, we'll talk briefly about default controllers, that is, the controller actions implied when not explicitly specified in your action bean using the @Controller annotation.

Controller Actions

The idea behind the controller action (also called action controller) is that common request processing logic can be abstracted and reused across many actions. For example, simple CRUD web applications typically use three types of request handling logic:

The example below shows the implementation of a controller handling form submission:

@ActionInterface(name = BasicSubmitAction.class)
public class BasicSubmitController extends BaseBasicController
{

    @Override
    protected ViewAdapter executeAction(Object actionBean, ActionContext context)
    {
    
        BasicSubmitAction action = (BasicSubmitAction) actionBean;
        ActionForm form = context.getForm();
    
        HttpServletRequest request = context.getRequest();
    
        boolean cancelled = false;
        if (request.getAttribute(Globals.CANCEL_KEY) != null)
        {
            cancelled = true;
        }
    
        if (form instanceof BindingForm && !cancelled)
        {
            action.preBind();
            BindingForm bindingForm = (BindingForm) form;
            bindingForm.bindInwards();
        }
    
        String result = cancelled ? action.cancel() : action.execute();
        return getActionForward(context, result);
    
    }

}

Notice that there is no application-specific code present. All that is present is request processing logic, which can be reused. A number of pre-packaged action controllers are available, including form handling controllers as well as dispatch controllers which mimic the behaviour of DispatchAction, MappingDispatchAction and LookupDispatchAction.

Action Beans

With request processing logic abstracted into a controller, all that remains for an action implementation is to implement the domain-specific aspects of each operation. This is the job of the action bean.

In Strecks, the action bean is registered in struts-config.xml exactly as if it were a regular Action. When used for the first time, an annotation on the action bean's class definition is used to identify the controller. An instance of the controller is created. The controller, which extends Action, is held in the action cache for subsequent requests. Each time a request is received, the controller creates a new instance of the action bean. The action controller itself holds no state, and is shared among multiple requests.

Lets take a look at an action bean implementation. SubmitEditBookingAction, shown below, is invoked when submitting an update from the "Edit Holiday Booking" form.

@Controller(name = BasicSubmitController.class)
public class SubmitEditBookingAction implements BasicSubmitAction
{

    private HolidayBookingForm form;

    private HolidayBookingService holidayBookingService;

    private WebHelper webHelper;

    public void preBind()
    {
    }

    public String cancel()
    {
        webHelper.setRequestAttribute("displayMessage", "Cancelled operation");
        webHelper.removeSessionAttribute("holidayBookingForm");
        return "success";
    }

    public String execute()
    {
        HolidayBooking holidayBooking = form.getBooking();
        holidayBookingService.updateHolidayBooking(holidayBooking);

        webHelper.setRequestAttribute("displayMessage", 
            "Successfully updated entry: " + holidayBooking.getTitle());
        webHelper.removeSessionAttribute("holidayBookingForm");

        return "success";
    }
    
    //dependency injection setters omitted
    
}

The action bean uses BasicSubmitController, which mandates that action bean collaborators implement the BasicSubmitAction interface. SubmitEditBookingAction does so by implementing the preBind(), cancel() and execute() methods.

Notice how the application-specific code in the action bean is no longer responsible for request processing logic. Consider cancel(), which is invoked when a user clicks on a button rendered using the <html:cancel/>; tag. The logic for determining whether a form has been cancelled is implemented in the controller, not the action bean.

Default Controllers

Strecks has built-in support for a number of controller actions, each associated with a particular action bean interface. For simple applications, it is quite likely that certain action beans implementing one of these interfaces (e.g BasicAction) will always be associated with a particular controller (BasicController). In these cases, the @Controller interface is somewhat redundant, because it always specifies the same controller action. To save having to explicitly declare the controller for each action bean, it makes sense to have a default controller associated with each interface.

The example below provides an illustration. The action bean ExampleImplicitAction does not declare its controller. Instead, the identity of the controller defaults to the class associated with the BasicAction interface, namely BasicController.

//this information is implied: @Controller(name = BasicController.class)
public class ExampleImplicitAction implements BasicAction
{
    public String execute()
    {
        return "success";
    }
}

By default, the following action bean interface default controllers apply.

Action Interface Default Controller
org.strecks.action.BasicAction org.strecks.action.basic.BasicController
org.strecks.action.BasicFormAction org.strecks.action.basic.BasicFormController
org.strecks.action.BasicSubmitAction org.strecks.action.basic.BasicSubmitController
org.strecks.action.BasicDispatchAction org.strecks.action.basic.BasicDispatchController
org.strecks.action.NavigableAction org.strecks.action.navigable.NavigableController
org.strecks.action.NavigableFormAction org.strecks.action.navigable.NavigableFormController
org.strecks.action.NavigableSubmitAction org.strecks.action.navigable.NavigableSubmitController
org.strecks.action.NavigableDispatchAction org.strecks.action.navigable.NavigableDispatchController
SourceForge.net logo java.net Member logo Copyright © 2005-2007 Realsolve Solutions