ingo.harbeckno@iharbeck.de
SourceForge.net Logo

Strutter

Strutter is an open-source extention to the web application framework Apache Struts.

The configuration of Struts is done in a central XML configuation file (struts-config.xml).
The goal of Strutter is to reduce and automate the configuration effort in XML by following conventions. In most projects you will never touch it again.

I experienced a lot of stupid and error prone copy-past tasks in my Struts development cycle. I try to eliminate them with this project. Finding target for my ActionForwards frustrated me in large struts-config.xml files. Sharing a single file in a multi developer project is no big fun also.

With Strutter all configuration is stored within the action itself. It's a tag interface configuration concept. The configuration is done directly in the code and you can use the code completion features provided by your IDE. This eliminates typing of full qualified classname for Actions or ActionForms.

Best of all, you don't need to switch legacy systems to the Strutter configuration concept completly. This extention can run in parallel with your existing struts configuration file.

The core of this extention is Strutter Config it will handle the configuration.

Strutter View is an optional part designed to extend the view of Struts MVC model.

It is the result of expiriences with the Struts tag library in a lot of projects. Strutter View will automatically map the ActionForm attributes to the HTML form elements. This is done by the name attribute of the elements. Strutter is parsing the final HTML provided in the request and fills in all missing data. It can handle pages provided as JSPs or from other scripting engines.
The goal is standard HTML. Because the requests are handled by the container first - you still have the option to mix up with the old fashioned way too.

Strutter Extentions. Strutter provides entended versions of the default Action and ActionDispatcher making live a little easier and provides execute functions without parameter. The FormlessInterface interface provides a simple way to get rid off the additional ActionForm. All form attributes can be added to the action itself.

Strutter Config

Features
  • Configure Struts by following conventions
  • Configure less and in your action class with code completion
  • Compatible with your existing Struts configuration
  • (Option) Formless Actions (Thread Safe)
  • Package by layer(some folder) or feature(JSPs next to your classes)
  • (Option) Interceptors

    The default conventions

  • Action and corresponding ActionFrom (if any) are located in the same folder
  • Action and ActionForm classname end with a suffix like Action and ActionForm
  • Action and ActionForm are starting with the same prefix
  • Action prefix is simular to the Actions classname
  • ActionForm name equals ActionForm classname
  • (Option) JSPs end with ActionForward's name

    Benefits

  • Reduce copy and past
  • Reduce configuration
  • Reduce errors
  • Better support for development in teams
  • Codecompletion without plugins
  • Compatible with JDK1.4

    Example 1 (Dispatcher Pattern)

    /* The Action */
    package example;
    
    public class CustomerAction extends ActionDispatcher implements ConfigInterface
    {
      public void config(ActionConfig struts) {
        struts.addForward("/customer_view.jsp");
      }
      
      ...
    }
    
    /* Optional ActionForm Class (is found by classname matching) */
    package example;
    
    public class CustomerActionForm extends ActionForm
    {
      ...
    }
    
    Example 2 (Multiple Action Pattern)
    /* The Action */
    package example;
    
    public class CustomerEditAction extends Action implements ConfigInterface
    {
      public void config(ActionConfig struts) {
        struts.addForward("/customer_view.jsp");
      }
    }
    
    /* Optional ActionForm Class */
    package example;
    
    public class CustomerEditActionForm extends ActionForm
    {
      ...
    }
    
    or
    
    public class CustomerActionForm extends ActionForm
    {
      ...
    }
    

    Behind the scenes: Equivalent configuration (Dispatcher Pattern):

    <form-beans>
        <form-bean name="CustomerActionForm" type="example.CustomerActionForm" />
    </form-beans>
    
    <action-mappings>
        <action name="CustomerActionForm"
                type="example.CustomerAction"
                parameter="action"
                scope="session"
                path="/customer">
                <forward name="view" path="/customer_view.jsp" />
        </action>
    </action-mappings>
    
    All struts configuration is done dynamically during the startup of the struts plugin modules.

    Installation
    Strutter Config is implemented as Struts Plugin. To setup with default configuration just add the stutter.jar and htmlparser.jar to your WEB-INF/lib and add the following tag to your struts-config.xml.

    <plug-in className="strutter.config.ActionPlugin" />
    
    That's it! The plugin searches your classpath for classes implementing
  • ConfigInterface
  • ConfigZeroInterface
  • ConfigWSInterface
  • ConfigAutorunInterface
  • ConfigRemoteInterface and will add the actions configuration programmatically on your applications startup.

    Customize conventions
    You can change some of default behavier.

    <plug-in className="strutter.config.ActionPlugin">
        	<set-property property="packageroot"  value="action"/>
        	<set-property property="aliasaction"  value="Action"/>
        	<set-property property="aliasform"    value="ActionForm"/>
        	<set-property property="aliasview"    value="view,list,update,create"/>
        	<set-property property="pathformat"   value="{PATH}"/>
        	<set-property property="pathlower"    value="0"/>
        	<set-property property="parameter"    value="action"/>
        	<set-property property="scope"        value="session"/>
        	<set-property property="views"        value="views"/>
    
        	<set-property property="encoding"     value="UTF-8"/>
        	<set-property property="viewer"       value="1"/>
        	<set-property property="keepalive"    value="1"/>
        	<set-property property="script"       value="1"/>
        	<set-property property="template"     value="1"/>
    
        	<set-property property="packageby"    value="layer"/>
       
    </plug-in>
    
    name default description
    packageroot action Comma separated list of package path
    aliasaction Action Suffix to identify ActionClass
    aliasform ActionForm Suffix to identify ActionFormClass
    aliasview view,list,update,create Suffix of default views (used only if no other forwards are provided) Example: actionname_alias.jsp
    pathformat {PATH} Formatting of Actionpath. Example "Frm{PATH}" to add Frm in front of PATH generated from the action's classname
    pathlower 0 1: convert PATH to lower, 0: PATH is unchanged
    parameter action Parameter for DispatcherAction alias variable
    views views Default folder storing JSPs
    encoding UTF-8 Default Encoding for rendered page
    viewer 1 1:Render HTML Tags (please see) Strutter View 0:disabled
    keepalive 1 1:AJAX request is send to keep session alive 0:disabled
    script 1 1:Support Javascript is render 0:disabled
    template 1 1:Support HTML for background processing is render 0:disabled
    packageby layer layer:Get JSP from folder relative to WEB ROOT package:lookup in class folder

    Optional configuration
    The following functions you can overwrite the configuration generated by the plugin.

      struts.addForward("view", "/customer_view.jsp", [redirect:false]);
      struts.addForward("/customer_view.jsp", [redirect:false]);
    
      struts.addGlobalForward("view", "/customer_view.jsp", [redirect:false]);
      struts.addGlobalForward("/customer_view.jsp", [redirect:false]);
    
      struts.setPackageby(ActionConfig.PACKAGEBY_FEATURE);
      struts.setForm(CustomerActionForm.class);
      struts.setValidate(false);
      struts.setInput("/customer_input.jsp");
      struts.setParameter("action");
      struts.setPath("/customer");
      struts.setScope("session");
      struts.setUnknown(false);
      struts.setRoles("role1,role2");
    
    name description
    struts.addForward(String alias, String path, boolean redirect) Add ActionForward
    Option: addForward will lookup the forward's name between "_**name**." Example: "/customer_view.jsp" -> "view". If the lookup fails the default name is "success".
    struts.addGlobalForward(String alias, String path, boolean redirect) Simular to addActionForward but registers the Forward as global.
    struts.setPackageBy(String packageby) Set jsp lookup mode
  • ActionConfig.PACKAGEBY_LAYER
  • ActionConfig.PACKAGEBY_FEATURE.
  • struts.setForm(class ActionForm) Manually assign an ActionForm to the Action.
    Option: If not provided Strutter will search for the ActionForm following two naming conventions:
    Class CustomerEditAction will search for CustomerEditActionForm and CustomerActionForm (in this order)
    struts.setValidate(boolean enable) Enable Validation.
    struts.setInput(String path) Set path for the input page. Used by Struts to redirect to when validation failed.
    struts.setParameter(String parameter) Set additional parameter used by ActionDispatcher class. Default value is "action".
    struts.setPath(String path) Set path for this action. If not provided Strutter will build the path following this conversation: CustomerAction -> customer.
    struts.setScope(String scope) Set scope of ActionForm.
    struts.setUnknown(boolean enable) Set this action as default action for the application.
    struts.setRoles(String roles) Comma separated list of roles.

    Strutter View

    Features
  • Automatic ActionForm population in standard HTML Tags
  • Option Tag handler with multiple sources
  • adds hidden field for action handler
  • adds Javascript to submit form subber
  • adds Javascript to submit form confirmed subberconfirm
  • adds keep alive, server is pinged via AJAX and the session will not expired
  • adds background processing subbernowait

    Example 1

      <form action="sample.do">
    
        <select name="anrede">
          <option id="anreden" />
        </select>
    
        <input type="text" name="firstname">
    
        <input type="button" onclick="subber('update')" value="OK">
    
      </form>
    
    This example will map the ActionForm attribut anrede to the select field anrede and firstname to the corresponding form attribut.
    The option values can be added manual or will be read from the attribute anreden. It will try to locate it in session, request, actionform (in this order). Nothing special just simple HTML.

    Error Handler
    There is a simple extention to handle error messages:

    <input type="text" name="firstname" error="behind">
    
    errortextclass
    behindError text behind the controlerror_label
    beforeError text before the controlerror_label
    classSet error class in case of errorerror_control

    The error message for each control is identified by the controls name.

    div / span
    Show form/request/session property with id label.name:

    <span type="text" id="label.name"/>
    
    Show resource message with id label.name:
    <span type="resource" id="label.name"/>
    
    Show all messages as list:
    <div type="messages" />
    
    Show all errors as list:
    <div type="errors" />
    
    Show error with id firstname:
    <div type="error" id="firstname"/>
    
    Disable processing a form element
    To disable processing of a single form element add the attribute nofill="nofill"

    Installation
    Strutter View is implemented as Filter. To get it running in just add the stutter.jar and htmlparser.jar to your WEB-INF/lib and add the following tag to your web.xml.

    <filter>
      <filter-name>strutterview</filter-name>
      <filter-class>strutter.view.PageFilter</filter-class>
    </filter>
    
    <filter-mapping>
      <filter-name>strutterview</filter-name>
      <url-pattern>*.do</url-pattern>
    </filter-mapping>
    
    The rendered page will be processed by the filter. All INPUT, SELECT, TEXTAREA are compared with the ActionForm and the tags value is filled with the forms content of the corresponding attibute.

    Strutter Extentions

    Features
  • ActionHelper
  • Formless Action
  • Plain Action
  • Interceptor (Action and Request based)

    ActionHelper
    The ActionHelper provides direct access to the request context.
    The following static functions are provided:

    To add an error or message to your request just call the addError(...) or addMessage(...) function. You do not need to take care about the ArrayList handling you normaly have to.

    Plain Action

  • PlainDispatchAction
  • PlainAction

    Subclass your Action class from one of the above classes allows you to use a simpler Action Method.
    It has no parameter instead of the four standard Struts parameter. (mapping, actionform, request, response)

    They still can be accessed via ActionHelper see above.

    If the action has both Action Method with and without parameter. The one with parameter will have priority one.

    Formless Action

  • FormlessInterface
  • FormlessDispatchAction (deprecaded)
  • FormlessAction (deprecaded)

    Implement the FormlessInterface in your ActionClass. Your Action will behave like a ActionForm. All Form attributes can be included directly in the action. The implementation is thread safe! You can access the form in the JSP like any other form.
    Traditional Struts Tag are working properly.

    If you provide an ActionForm the Formless funcionality is disabled automaticaly and the ActionForm will be filled instead!

    /* The Action */
    package example;
    
    public class CustomerAction extends PlainDispatchAction implements ConfigInterface, FormlessInterface
    {
      public void config(ActionConfig struts) {
        struts.addForward("/customer_view.jsp");
      }
    
      public void reset() {
      }
    
      public ActionForward view() {
    
        //...
        
    	  ActionHelper.getRequest();  // ThreadLocal access to environment	
        
        //...
    
        return ActionHelper.findForward("view");
      }
    
      String memo; // add some form attributes (They are handled Thread Safe)
      
      //... getter and setter for "memo" ...
    }
    
    SQLHelper
    Webservice
    Autorun
    Remote
    TODO add documentation.