Struts 2 > Quick Start Guide |
WebWork is a popular, easy-to-use MVC framework, for more information on the WebWork project, please visit Home. 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.
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):
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.
<?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-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.
Note:
As of Webwork 2.2, the use of ServletDispatcher is being deprecated but instead replaced with FilterDispatcher. The above mapping could be done as follows using FilterDispatcher.
<?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> <filter> <filter-name>webwork</filter-name> <filter-class>com.opensymphony.webwork.dispatcher.FilterDispatcher</filter-class> </filter> <filter-mapping> <filter-name>webwork</filter-name> <url-pattern>/*</url-pattern> </filter-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>
<filter-mapping> <filter-name>webwork</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
The above will map any url request in the particular context path to the Webwork's FilterDispatcher. Webwork knows that url with *.action are webwork action through the combination of 'webwork.action.extension' and 'webwork.mapper.class' defined in webwork.properties.
<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.
<?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>
<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.
<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 Result Types.
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:
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]
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; } ... }
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:
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.
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