This page last changed on Nov 08, 2004 by matthew.

WebWork is a popular, easy-to-use MVC framework, for more information on the WebWork project, please visit WW:WebWork. This guide should be helpful to seasoned Java developers with previous experience in MVC frameworks. We will briefly cover the three main components on a WebWork2 based application, the configuration the action classes, and the views.

GETTING STARTED

To use WebWork as your framework for writing Java-based web applications, you need to start by installing the various libraries (these are all available in the webwork 2.x distribution):

Core JAR files

Optional JAR files

  • jstl.jar (needed for Standard Tag Libraries)
  • cos-multipart.jar
  • pell-multipart.jar
  • standard.jar
  • mail.jar

CONFIGURATION

WebWork is built upon the Xwork framework. Xwork handles the translation requests to commands execution, but let's not worry about that right now. You need to know this information in case you were curious about the xwork JAR file, and if you want to learn some of the more advanced features of the WebWork command structure, you can visit the XW:XWork site.

Example web.xml file

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app 
          PUBLIC 
          "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" 
          "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
    <display-name>WebWork 2.0 Quick Start</display-name>
    <servlet>
        <servlet-name>webwork</servlet-name>
          <servlet-class>com.opensymphony.webwork.dispatcher.ServletDispatcher</servlet-class>                                            
    </servlet>


    <servlet-mapping>
        <servlet-name>webwork</servlet-name>
	<url-pattern>*.action</url-pattern>
    </servlet-mapping>


    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

    <taglib> 
        <taglib-uri>webwork</taglib-uri> 
        <taglib-location>/WEB-INF/lib/webwork-2.1.5.jar</taglib-location> 
    </taglib>

</web-app>

Servlet mappings

<servlet-mapping>
    <servlet-name>webwork</servlet-name>
    <url-pattern>*.action</url-pattern>
</servlet-mapping>

The above section will map ANY servlet called with an extension of .action to the WebWork base servlet, and assume it is a WebWork action class.

Taglibs

<taglib> 
  <taglib-uri>webwork</taglib-uri> 
  <taglib-location>/WEB-INF/lib/webwork-2.1.5.jar</taglib-location> 
</taglib>

The above section will load the standard WebWork tag libraries. This is required for JSP 1.1 compatible containers. To load more or different libraries, add more <taglib> calls.

Example Xwork config file (xwork.xml)

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE xwork 
          PUBLIC 
          "-//OpenSymphony Group//XWork 1.0//EN" 
          "http://www.opensymphony.com/xwork/xwork-1.0.dtd">
<xwork>
    <include file="webwork-default.xml"/>
    <package name="default" extends="webwork-default">
        <interceptors>
                <interceptor name="security" class="com.acme.LoginCheck"/>
                <interceptor-ref name="defaultStack"/>
        </interceptors>

        <default-interceptor-ref name="security"/>
       
        <action name="showForm" class="com.acme.FormAction">
            <result name="success" type="dispatcher">
                <param name="location">/form.jsp</param>
            </result>
        </action>

        <action name="saveForm" class="com.acme.FormAction" method="processForm">
            <result name="success" type="dispatcher">
                <param name="location">/form.jsp</param>
            </result>
             <result name="missing-data" type="dispatcher">
                <param name="location">/form.jsp</param>
            </result>
            <interceptor-ref name="security"/>
        </action>

    </package>
</xwork>

ACTIONS

<action name="saveForm" class="com.acme.FormAction" method="processForm">

Actions are the basic "unit-of-work" in WebWork, they define, well, actions. An action will usually be a request, (and usually a button click, or form submit). The main action element (tag is too synonymous with JSP) has two parts, the friendly name (referenced in the URL, i.e. saveForm.action) and the corresponding "handler" class.

The method parameter tells WebWork which method to call based upon this action. If you leave the method parameter blank, WebWork will call the method execute() from the Action Interface by default. Since every Action must implment the Action Interface, this method will always be available.

RESULTS

<result name="missing-data" type="dispatcher">
    <param name="location">/form.jsp</param>
</result>

Result tags tell WebWork what to do next after the action has been called. There are a standard set of result codes built-in to WebWork, (in the Action interface) they include:
String SUCCESS = "success";
String NONE    = "none";
String ERROR   = "error";
String INPUT   = "input";
String LOGIN   = "login";

You can extend these as you see fit. Most of the time you will have either SUCCESS or ERROR, with SUCCESS moving on to the next page in your application;

<result name="success" type="dispatcher">
    <param name="location">/thank_you.jsp</param>
</result>

…and ERROR moving on to an error page, or the preceding page;
<result name="error" type="dispatcher">
    <param name="location">/error.jsp</param>
</result>

You can stack as many result tags within a single action tag as you wish.

For further reading on Result types, see WW:Result Types.

INTERCEPTORS

Interceptors allow you to define code to be executed before and/or after the execution of an action. Interceptors can be a powerful tool when writing web applications. Some of the most common implementations of an Interceptor might be:

  • Security Checking (ensuring the user is logged in)
  • Trace Logging (logging every action)
  • Bottleneck Checking (start a timer before and after every action, to check bottlenecks in your application)

You can also group Interceptors together to create "stacks". If you wanted to do a login check, security check, and logging all before an Action call, this could easily be done with an interceptor stack.

For further Reading on Interceptors, see XW:Interceptors
For further Reading on Xwork configuration files, see XW:Configuration

ACTION CLASSES

The action classes do what they say, they handle the action. They are called by the actions specified in the xwork.xml file and initiated by the user in the "views". To turn your class into an action class, you simply need to extend the class ActionSupport or implement the Action interface.

Here is what our saveForm action looks like in its Java form (NOTE: If you look in the xwork.xml file above, we've overridden the action to call the processForm method):

package com.acme;
import com.opensymphony.xwork.*;

public class FormAction extends ActionSupport {
    
    private FormBean myFormBean = new FormBean();

    public void setFormBean(FormBean inBean) {
        myFormBean = inBean;
    }

    public FormBean getFormBean() {
        return myFormBean;
    }

    public String processForm() {

        FormParameters formParams = this.getFormBean();
        checkBizRules(formParams);
        this.saveParamsToDb(formParams);

        return SUCCESS;
    }
...
}

VIEWS

WebWork supports JSP, Velocity, and FreeMarker for your application presentation layer. For this example, we will use a JSP file. The appropriate presentation layer is denoted by the result type specified. For JSPs, the result type is the name mapped to the com.opensymphony.webwork.dispatcher.ServletDispatcherResult. Typically, this is "dispatcher".

WebWork comes packaged with a tag library (taglibs). You can use these taglibs as components in your JSP file. Here is an section of our form.jsp page:
<%@ taglib prefix="ww" uri="webwork" %>
<html>
<head><title>Webwork Form Example</title></head>
<body>

<ww:form name="'myForm'" action="'saveForm.action'" method="'POST'">
    <table>

    <ww:textfield label="'First Name'" name="'formBean.firstName'" value="formBean.firstName"/>
    <ww:textfield label="'Last Name'" name="'formBean.lastName'" value="formBean.lastName"/>

    </table>
    <input type="submit" value="Save Form"/>
</ww:form>
</body>

The process of events will go as follows:

  1. WebWork will take notice since the URI ends in .action (defined in our web.xml files)
  2. WebWork will look up the action saveForm in its action hierarchy and call any Interceptors that we might have defined.
  3. WebWork will translate saveForm and decide we would like to call the method processForm in our class com.acme.FormAction as defined in our xwork.xml file.
  4. Our method will process successfully and give WebWork the SUCCESS return parameter.
  5. WebWork will translate the SUCCESS return parameter into the location thank_you.jsp (as defined in xwork.xml) and redirect us accordingly.

SUMMARY

The purpose of this guide is to provide the user with a quick-and-dirty understanding of WebWork2. I hope we successfully briefed you on the three most important components of any WebWork based application, the configuration (including web.xml and xwork.xml), the action classes, and the views. This information should give you a starting point to experiment and become more familiar with the rising star of the open source, Model2, web frameworks.

Miscellaneous Notes

It is not necessary to map and load the WebWorkVelocityServlet in in the web.xml in order to use Velocity rendered pages. WebWork includes a built-in Velocity result type. Using the result type should be faster than sending the result to the servlet dispatcher which then delegates to the servlet mapping for WebWorkVelocityServlet.

Originally by:
Matt Dowell
matt.dowell@notiva.com
September 15, 2003

Document generated by Confluence on Dec 14, 2004 16:36