TODO: There is a lot of overlapping info at XWork Configuration.
Example
Code Block | ||||
---|---|---|---|---|
| ||||
<?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-stack name="defaultComponentStack"> <interceptor-ref name="component"/> <interceptor-ref name="defaultStack"/> </interceptor-stack> </interceptors> <default-interceptor-ref name="defaultStack"/> <action name="SimpleCounter" class="com.opensymphony.webwork.example.counter.SimpleCounter"> <result name="success" type="dispatcher">/success.jsp</result> <interceptor-ref name="defaultComponentStack"/> </action> <!-- - Velocity implementation of the SimpleCounter. Also demonstrate a more verbose version of result element --> <action name="VelocityCounter" class="com.opensymphony.webwork.example.counter.SimpleCounter"> <result name="success" type="velocity"> <param name="location">/success.vm</param> </result> <interceptor-ref name="defaultComponentStack"/> </action> <!-- - Different method can be used (processForm). --> <action name="formTest" class="com.opensymphony.webwork.example.FormAction" method="processForm" > <result name="success" type="dispatcher">/formSuccess.jsp</result> <result name="invalid.token" type="dispatcher">/form.jsp</result> <interceptor-ref name="defaultStack"/> <interceptor-ref name="token"/> </action> </package> </xwork> |
Actions
Code Block | |
---|---|
xml | xml|
<action name="formTest" class="com.opensymphony.webwork.example.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 optional "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() by default. If there is no execute() method and no method specified in the xml file, WebWork will throw an exception.
Also, you can tell WebWork to invoke "doSomething" method in your action by using the pattern "actionName!something" in your form. For example, "formTest!save.action" will invoke the method "save" in FormAction class. The method must be public and take no arguments:
Code Block |
---|
public String save() throws Exception
{
...
return SUCCESS;
}
|
All the configuration for "actionName" will be used for "actionName!something" (interceptors, result types, etc...)
Results
...
<result name="missing-data" type="dispatcher">
<param name="location">/form.jsp</param>
<param name="parameterA">A</param>
<param name="parameterB">B</param>
</result>
Result tags tell WebWork what to do next after the action has been called. The "name" attribute maps to the result code returned from the action execute() method. The "type" attribute indicates what result type class to use (see Result Types). The "param" elements allow you to pass parameters to
the view:
...
<result-types>
....
<result-type name="header"
class="com.opensymphony.webwork.dispatcher.HttpHeaderResult"/>
</result-types>
<result name="no-content" type="header">
<param name="status">204</param>
<param name="headers.customHeaderA">A</param>
<param name="headers.customHeaderB">B</param>
</result>
There are a standard set of result codes built-in to WebWork, (in the Action interface) they include:
Code Block |
---|
Action.SUCCESS = "success";
Action.NONE = "none";
Action.ERROR = "error";
Action.INPUT = "input";
Action.LOGIN = "login";
|
You can extend these result codes as you see fit (i.e "missing-data"). Most of the time you will have either SUCCESS or ERROR, with SUCCESS moving on to the next page in your application.
If you only need to specify the "location" parameter, you can use the short form:
Code Block |
---|
<result name="missing-data" type="dispatcher">/form.jsp</result>
|
See webwork-default.xml or Result Types for standard 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 chain Interceptors together to create an interceptor stack. 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 package.
Intercepters must first be defined (to give name them) and can be chained together as a stack:
...
<interceptors>
<interceptor name="security" class="com.mycompany.security.SecurityInterceptor"/>
<interceptor-stack name="defaultComponentStack">
<interceptor-ref name="component"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
To use them in your actions:
...
<action name="VelocityCounter" class="com.opensymphony.webwork.example.counter.SimpleCounter">
<result name="success">...</result>
<interceptor-ref name="defaultComponentStack"/>
</action>
NOTE: Reference name can be either the name of the interceptor or the name of a stack
For more details, see Interceptors reference.
Views
WebWork supports JSP and Velocity for your application presentation layer. For this example we will use a JSP file. 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="'formTest'" namespace="/" 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"/>
<ww:submit value="Save Form"/>
</table>
</ww:form>
</body>
The process of events will go as follows:
- WebWork will take notice since the URI ends in .action (defined in web.xml files)
- WebWork will look up the action formTest in its action hierarchy and call any Interceptors that might have been defined.
- WebWork will translate formTest and decide to call the method processForm in the class com.opensymphony.webwork.example.FormAction as defined in xwork.xml file.
- The method will process successfully and give WebWork the SUCCESS return parameter.
- WebWork will translate the SUCCESS return parameter into the location formSuccess.jsp (as defined in xwork.xml) and redirect accordingly.
Include
To make it easy to manage large scale development (lots of actions + configuration), WebWork allows you to include other configuration files from xwork.xml :
...
<xwork>
<include file="webwork-default.xml"/>
<include file="user.xml"/>
<include file="shoppingcart.xml"/>
<include file="product.xml"/>
....
</xwork>
The included files must be the same format as xwork.xml (with the doctype and everything) and be placed on classpath (usually in /WEB-INF/classes or jar files in /WEB-INF/lib).
Most of the content here provided by Matt Dowell <matt.dowell@notiva.com>For more information about the configuration details see XWork Configuration