Presentation Layer

The presentation layer is one of the main focus of the struts-It architecture. The most things might be solved by using a presentation framework like struts. But not all aspects of the presentation layer are unnecessary by using a dedicated framework. Mostly the technical aspects of an application like event-action-mapping, data transforming, validating and so on are mapped. Aspects of business applications such like assistance of use cases, connecting to the business logic are often fade out.

Offering a use case context for applications

Webapplications, that are deployed in a servlet container, have usually some problems to save their state. For state information across the session normally a session context is offered in the servlet container. But this context has some problems:

  • The data are not well typed because they are stored into hashmaps with a key/value aproach. So problems with wrong type casts might come into being at runtime.

  • Many entries will be accumulate so that nobody has an overview of entries which had saved. Nobody takes care that the entries will be deleted so requests have access to data that aren't designed for them.

  • Most applications are use case driven. Certainly there is no context for use cases in a technical framework. So several use cases uses the session context for saving their data.

Struts-it offers in the presentation layer a context for use case driven design. As an add on for several presentation framework an abstraction for actions and use case context are implemented.

Data in a context may be stored in several ways. In JavaBean-manner attributes will be stored and loaded by special set- and get-methods. It is also best practice to store and load values in the manner of contextes. So it is recommanded that JavaBeans properties added to a particular Context implementation exhibit Attribute-Property Transparency. In other words, a value stored via a call to setFoo(value) should be visible by calling get("foo"), and a value stored via a call to put("foo", value) should be visible by calling getFoo().

The commons-chain implementation offers a generic mechanism to handle such Attribute-Property Transparency. All properties will be determined on the instaciation of the context. So it is possible to delegate a get-/put-call to the corresponded property, if exists.

The struts-it context is a commons-chain context with some enhancements.

  • Checkpoints for measuring performance. If you wish, the measuring points will be automatically added by the struts request processor.

  • Use case scope. In bundle with the StrutsItRequestProcessor the context offers a container for a particular use case.

  • To be continued.

Offering a standardized abstract action

Presentation frameworks like struts offers their own implementation for fine granular actions. Struts-it offers an action-interface (StrutsItAction) that can deal with StrutsItContext-Objects. Struts-it also offers an generic action implementation for a use case driven aproach. For the struts framework struts-it also provide specialized action implementations for different presentation frameworks.

The core of the presentation layer is platform independed but struts is the favorite framework to work together with struts-it. Struts-it offers two base interfaces: StrutsItAction and StrutsItContext. For the struts framework there is also an StrutsItRequestProcessor that can deal with struts-it actions and contextes and some other default implementations.

StrutsItContext: This Context hold all the information that a action needs such as request, response, servlet instance and beside that some things of special frameworks. The struts implementation will also hold informations as mapping informations. The context also share data across the hooks and can be recycled for more than one request. For that you are able to share informations over several requests e.g. across a use-case.

StrutsItAction: The struts-it action-class is enhanced for an other execute methode (only gets a context with it) and some other methods. Struts-it actions can be used as filters, that will proceeded by every request. Because the struts-it Action is an interface, it may inherited some special struts action classes e.g. DispatchAction.

StrutsItRequestProcessor: This request-processor can deal with StrutsItAction classes. The processor offers a hook. The hook is, different to struts, embedded in the struts exception handling mechanism and works like filters or interceptors. The hook calls configured action classes that can fulfill some general things. There is a preprocess- and a postprocess hook that can execute action classes. For details see next section. This specialized request processor can also act as a normal request processor. So you are able to mix original struts actions with those from the struts-it extensions.

Offering a pre- and postprocess hook for struts with embending the struts exception handling

Therer are two good concepts in the struts framework that unfortunately fit not together.

  1. The request processor offers a preprocessing hook, where the application can place some additional things like filtering, enhancing the request.

  2. For generel exceptions struts offers exception-handler that can be configured in the struts-config.xml.

But:

  • It ist not possible to configure action-classes in the hook.

  • If the hook implementation throws an exception it is not catched by the general exception handlers.

  • There is only a preprocessing hook and not a postprocessing hook.

The struts-it mechanism harmonize these good struts concepts.

Offering hooks where action classes can be configured

Harmonizing the struts exception handling for all actions also actions that are configured in hooks

Configuration of the presentation extensions

Struts-it comes with a seperate XML-Configuration. The configuration ist use case based.

   
  <struts-it context-implementation="org.strutsit.context.impl.StrutsContext">

      <preprocessing>
          <action name="org.strutsit.actions.PreProcess/>
          <action name="org.strutsit.actions.PreProcess2/>
      </preprocessing>

      <postprocessing>
          <action name="org.strutsit.actions.PostProcess/>
          <action name="org.strutsit.actions.PostProcess2/>
      </postprocessing>

      <use-case name="Add Customer" sharecontext="true"
                                    usemeasuring="true"
                                    processglobalpre="true"
                                    processglobalpost="true">
      </use-case>

  </struts-it>