Source

webwork / docs / wikidocs / TutorialLesson03.html

Full commit
<html>
    <head>
        <title>WebWork 2 : TutorialLesson03</title>
	    <link rel="stylesheet" href="styles/site.css" type="text/css" />
        <META http-equiv="Content-Type" content="text/html; charset=UTF-8">	    
    </head>

    <body>
	    <table class="pagecontent" border="0" cellpadding="0" cellspacing="0" width="100%" bgcolor="#ffffff">
		    <tr>
			    <td valign="top" class="pagebody">
				    <div class="pageheader">
					    <span class="pagetitle">
                            WebWork 2 : TutorialLesson03
                                                    </span>
				    </div>
				    <div class="pagesubheading">
					    This page last changed on Sep 16, 2004 by <font color="#0050B2">vitorsouza</font>.
				    </div>

				    <p class="paragraph"><h1 style="margin: 4px 0px 4px 0px;" class="heading1"><a name="TutorialLesson03-Lesson3%3AActionsandResults"> Lesson 3: Actions and Results</a></h1></p>Actions are the basic unit of execution. An action is a class that is registered under WebWork&#039;s configuration to respond to a specific request. In a Model-View-Controller approach, the Action is part of the Controller, leaving to JSP pages what they do best: being the View.<p class="paragraph">The following steps are a possible way of creating an action in WebWork:</p><ol>
<li> Create a JSP page that will call the action;</li>
<li> Create the action class;</li>
<li> Create a JSP page that will process the result;</li>
<li> Register the action in <tt class="monospaced">xwork.xml</tt>.</li>
</ol><br/>
The first example of this tutorial could be no other than <em class="emphasis">&quot;Hello, WebWorld!&quot;</em>. The code below displays WebWork&#039;s configuration file <tt class="monospaced">xwork.xml</tt> with configuration for an action under the <tt class="monospaced">default</tt> package.
<p class="paragraph"><h3 class="heading3"><a name="TutorialLesson03-xwork.xml%3A"> xwork.xml:</a></h3>
<div class="code"><div class="codeContent">
<pre><span class="xml&#45;tag">&lt;&#33;DOCTYPE xwork PUBLIC <span class="xml&#45;quote">&quot;&#45;//OpenSymphony Group//XWork 1.0//EN&quot;</span>&#10;<span class="xml&#45;quote">&quot;&#104;ttp://www.opensymphony.com/xwork/xwork&#45;1.0.dtd&quot;</span>&gt;</span>&#10;&#10;<span class="xml&#45;tag">&lt;xwork&gt;</span>&#10;	<span class="xml&#45;tag"><span class="xml&#45;comment">&lt;&#33;&#45;&#45; Include webwork defaults (from WebWork JAR). &#45;&#45;&gt;</span></span>&#10;	<span class="xml&#45;tag">&lt;include file=<span class="xml&#45;quote">&quot;webwork&#45;default.xml&quot;</span> /&gt;</span>&#10;	&#10;	<span class="xml&#45;tag"><span class="xml&#45;comment">&lt;&#33;&#45;&#45; Configuration for the default package. &#45;&#45;&gt;</span></span>&#10;	<span class="xml&#45;tag">&lt;package name=<span class="xml&#45;quote">&quot;default&quot;</span> extends=<span class="xml&#45;quote">&quot;webwork&#45;default&quot;</span>&gt;</span>&#10;		<span class="xml&#45;tag"><span class="xml&#45;comment">&lt;&#33;&#45;&#45; Default interceptor stack. &#45;&#45;&gt;</span></span> &#10;		<span class="xml&#45;tag">&lt;default&#45;interceptor&#45;ref name=<span class="xml&#45;quote">&quot;defaultStack&quot;</span> /&gt;</span> &#10;		&#10;		<span class="xml&#45;tag"><span class="xml&#45;comment">&lt;&#33;&#45;&#45; Action: Lesson 03: HelloWebWorldAction. &#45;&#45;&gt;</span></span> &#10;		<span class="xml&#45;tag">&lt;action name=<span class="xml&#45;quote">&quot;helloWebWorld&quot;</span> class=<span class="xml&#45;quote">&quot;lesson03.HelloWebWorldAction&quot;</span>&gt;</span> &#10;			<span class="xml&#45;tag">&lt;result name=<span class="xml&#45;quote">&quot;success&quot;</span> type=<span class="xml&#45;quote">&quot;dispatcher&quot;</span>&gt;</span>ex01&#45;success.jsp<span class="xml&#45;tag">&lt;/result&gt;</span> &#10;		<span class="xml&#45;tag">&lt;/action&gt;</span> &#10;	<span class="xml&#45;tag">&lt;/package&gt;</span>&#10;<span class="xml&#45;tag">&lt;/xwork&gt;</span></pre>
</div></div></p>Don&#039;t worry about the <tt class="monospaced">default-interceptor-ref</tt> yet. For now we are interested in the action only. This configuration file is telling WebWork that there is an action called <tt class="monospaced">helloWebWorld</tt> which is implemented by the class <tt class="monospaced">lesson03.HelloWebWorldAction</tt>. For this action, we define a result under the name <tt class="monospaced">success</tt> which points to the web page <tt class="monospaced">ex01-success.jsp</tt>.<br/>

<blockquote class="blockquote"> Read more: <a href="xwork.xml.html" title="xwork.xml">xwork.xml</a></blockquote><p class="paragraph">Things should get clearer once we take a look at the code that calls the action:</p><h3 class="heading3"><a name="TutorialLesson03-ex01index.jsp%3A"> ex01-index.jsp:</a></h3>
<div class="code"><div class="codeContent">
<pre>&lt;html&gt;&#10;&lt;head&gt;&#10;&lt;title&gt;WebWork Tutorial &#45; Lesson 3 &#45; Example 1&lt;/title&gt;&#10;&lt;/head&gt;&#10;&#10;&lt;body&gt;&#10;&#10;&lt;p&gt;Click the button below to activate HelloWebWorldAction.&lt;/p&gt;&#10;&#10;&lt;form action=<span class="java&#45;quote">&quot;helloWebWorld.action&quot;</span> method=<span class="java&#45;quote">&quot;post&quot;</span>&gt;&#10;&lt;p&gt;&lt;input type=<span class="java&#45;quote">&quot;submit&quot;</span> value=<span class="java&#45;quote">&quot;Hello&#33;&quot;</span> /&gt;&lt;/p&gt;&#10;&lt;/form&gt;&#10;&#10;&lt;/body&gt;&#10;&lt;/html&gt;</pre>
</div></div><p class="paragraph">This is how web pages can integrate with WebWork: by accessing <tt class="monospaced">&#42;.action</tt> URLs. Recalling the previous lesson, that&#039;s why we registered WebWork&#039;s <tt class="monospaced">ServletDispatcher</tt> with mapping to <tt class="monospaced">&#42;.action</tt>.</p>When we click the button in our example page, the browser will send the form data to the URL <tt class="monospaced">helloWebWorld.action</tt>. Since this URL fits under the mapping <tt class="monospaced">&#42;.action</tt>, the Servlet container will activate WebWork&#039;s <tt class="monospaced">ServletDispatcher</tt>, which will read <tt class="monospaced">xwork.xml</tt> and look for an action called <tt class="monospaced">helloWebWorld</tt>. If the action is found, a <b class="strong">new</b> instance of the action class is created and the method <tt class="monospaced">execute()</tt> is called.<p class="paragraph">Let&#039;s see the action class, then:</p><h3 class="heading3"><a name="TutorialLesson03-HelloWebWorldAction.java%3A"> HelloWebWorldAction.java:</a></h3>
<div class="code"><div class="codeContent">
<pre><span class="java&#45;keyword">package</span> lesson03; &#10;&#10;<span class="java&#45;keyword">import</span> com.opensymphony.xwork.ActionSupport; &#10;&#10;<span class="java&#45;keyword">public</span> class HelloWebWorldAction <span class="java&#45;keyword">extends</span> ActionSupport &#123; &#10;	<span class="java&#45;object">String</span> hello; &#10;	<span class="java&#45;keyword">public</span>&#160;<span class="java&#45;object">String</span> getHello() &#123; &#10;		<span class="java&#45;keyword">return</span> hello; &#10;	&#125;&#10;	<span class="java&#45;keyword">public</span>&#160;<span class="java&#45;object">String</span> execute() <span class="java&#45;keyword">throws</span> Exception &#123; &#10;		hello = <span class="java&#45;quote">&quot;Hello, WebWorld&#33;&quot;</span>; &#10;		<span class="java&#45;keyword">return</span> SUCCESS; &#10;	&#125; &#10;&#125;</pre>
</div></div><p class="paragraph">First, notice that this class extends <tt class="monospaced">com.opensymphony.xwork.ActionSupport</tt> and implements the method <tt class="monospaced">public String execute()</tt>. For starters, all your action classes should do that. Second, notice that the method <tt class="monospaced">execute()</tt> only sets the value of the <tt class="monospaced">hello</tt> property and returns the constant <tt class="monospaced">SUCCESS</tt>, which is a String whose value is <tt class="monospaced">&quot;success&quot;</tt>.</p>When the ServletDispatcher gets <tt class="monospaced">&quot;success&quot;</tt> as return from <tt class="monospaced">execute()</tt>, it looks again at <tt class="monospaced">xwork.xml</tt> for a result with that name, finds it, and moves on to <tt class="monospaced">ex01-success.jsp</tt>, as specified in the configuration. <p class="paragraph">Let&#039;s see what that page does:</p><h3 class="heading3"><a name="TutorialLesson03-ex01success.jsp%3A"> ex01-success.jsp:</a></h3>
<div class="code"><div class="codeContent">
<pre>&lt;&#37;&#64; taglib uri=<span class="java&#45;quote">&quot;webwork&quot;</span> prefix=<span class="java&#45;quote">&quot;ww&quot;</span> &#37;&gt; &#10;&lt;html&gt; &#10;&lt;head&gt; &#10;&lt;title&gt;WebWork Tutorial &#45; Lesson 3 &#45; Example 1&lt;/title&gt; &#10;&lt;/head&gt; &#10;&lt;body&gt; &#10;&#10;&lt;ww:property value=<span class="java&#45;quote">&quot;hello&quot;</span> /&gt; &#10;&#10;&lt;/body&gt; &#10;&lt;/html&gt;</pre>
</div></div><p class="paragraph">If you run the example, you will see that this page will display <tt class="monospaced">&quot;Hello, WebWorld!&quot;</tt>. That happens because what the <tt class="monospaced">&lt;ww:property value=&quot;hello&quot; /&gt;</tt> tag does is look for the property <tt class="monospaced">hello</tt> in the action class that just executed. Actually, it looks for an accessor method, so it ends up calling <tt class="monospaced">getHello()</tt>. Since <tt class="monospaced">HelloWebWorldAction</tt> was called and set the value of the hello property to <tt class="monospaced">&quot;Hello, WebWorld!&quot;</tt>, <tt class="monospaced">getHello()</tt> will return that value and it will be displayed by the resulting JSP page.</p><blockquote class="blockquote"> <a href="TutorialExamples.html" title="TutorialExamples">Try the example!</a></blockquote>
<p class="paragraph"><h2 class="heading2"><a name="TutorialLesson03-SupplyingDatatotheAction"> Supplying Data to the Action</a></h2></p>The previous example demonstrated how WebWork&#039;s actions work, but we can&#039;t do much if we&#039;re not able to supply data to our action. Let&#039;s see an example that does just that:
<p class="paragraph"><h3 class="heading3"><a name="TutorialLesson03-xwork.xml%3A"> xwork.xml:</a></h3>
<div class="code"><div class="codeContent">
<pre><span class="xml&#45;tag">&lt;&#33;DOCTYPE xwork PUBLIC <span class="xml&#45;quote">&quot;&#45;//OpenSymphony Group//XWork 1.0//EN&quot;</span>&#10;<span class="xml&#45;quote">&quot;&#104;ttp://www.opensymphony.com/xwork/xwork&#45;1.0.dtd&quot;</span>&gt;</span>&#10;&#10;<span class="xml&#45;tag">&lt;xwork&gt;</span>&#10;	<span class="xml&#45;tag"><span class="xml&#45;comment">&lt;&#33;&#45;&#45; Include webwork defaults (from WebWork JAR). &#45;&#45;&gt;</span></span>&#10;	<span class="xml&#45;tag">&lt;include file=<span class="xml&#45;quote">&quot;webwork&#45;default.xml&quot;</span> /&gt;</span>&#10;	&#10;	<span class="xml&#45;tag"><span class="xml&#45;comment">&lt;&#33;&#45;&#45; Configuration for the default package. &#45;&#45;&gt;</span></span>&#10;	<span class="xml&#45;tag">&lt;package name=<span class="xml&#45;quote">&quot;default&quot;</span> extends=<span class="xml&#45;quote">&quot;webwork&#45;default&quot;</span>&gt;</span>&#10;		<span class="xml&#45;tag"><span class="xml&#45;comment">&lt;&#33;&#45;&#45; Default interceptor stack. &#45;&#45;&gt;</span></span> &#10;		<span class="xml&#45;tag">&lt;default&#45;interceptor&#45;ref name=<span class="xml&#45;quote">&quot;defaultStack&quot;</span> /&gt;</span> &#10;		&#10;		<span class="xml&#45;tag"><span class="xml&#45;comment">&lt;&#33;&#45;&#45; Action: Lesson 03: HelloAction. &#45;&#45;&gt;</span></span>&#10;		<span class="xml&#45;tag">&lt;action name=<span class="xml&#45;quote">&quot;hello&quot;</span> class=<span class="xml&#45;quote">&quot;lesson03.HelloAction&quot;</span>&gt;</span>&#10;			<span class="xml&#45;tag">&lt;result name=<span class="xml&#45;quote">&quot;error&quot;</span> type=<span class="xml&#45;quote">&quot;dispatcher&quot;</span>&gt;</span>ex02&#45;index.jsp<span class="xml&#45;tag">&lt;/result&gt;</span>&#10;			<span class="xml&#45;tag">&lt;result name=<span class="xml&#45;quote">&quot;success&quot;</span> type=<span class="xml&#45;quote">&quot;dispatcher&quot;</span>&gt;</span>ex02&#45;success.jsp<span class="xml&#45;tag">&lt;/result&gt;</span>&#10;		<span class="xml&#45;tag">&lt;/action&gt;</span>&#10;	<span class="xml&#45;tag">&lt;/package&gt;</span>&#10;<span class="xml&#45;tag">&lt;/xwork&gt;</span></pre>
</div></div></p><h3 class="heading3"><a name="TutorialLesson03-HelloAction.java%3A"> HelloAction.java:</a></h3>
<div class="code"><div class="codeContent">
<pre><span class="java&#45;keyword">package</span> lesson03;&#10;&#10;<span class="java&#45;keyword">import</span> com.opensymphony.xwork.ActionSupport;&#10;&#10;<span class="java&#45;keyword">public</span> class HelloAction <span class="java&#45;keyword">extends</span> ActionSupport &#123;&#10;	<span class="java&#45;object">String</span> person;&#10;	<span class="java&#45;keyword">public</span>&#160;<span class="java&#45;object">String</span> getPerson() &#123;&#10;		<span class="java&#45;keyword">return</span> person;&#10;	&#125;&#10;	<span class="java&#45;keyword">public</span> void setPerson(<span class="java&#45;object">String</span> person) &#123;&#10;		<span class="java&#45;keyword">this</span>.person = person;&#10;	&#125;&#10;	<span class="java&#45;keyword">public</span>&#160;<span class="java&#45;object">String</span> execute() <span class="java&#45;keyword">throws</span> Exception &#123;&#10;		<span class="java&#45;keyword">if</span> ((person == <span class="java&#45;keyword">null</span>) || (person.length() == 0)) <span class="java&#45;keyword">return</span> ERROR;&#10;		<span class="java&#45;keyword">else</span>&#160;<span class="java&#45;keyword">return</span> SUCCESS;&#10;	&#125;&#10;&#125;</pre>
</div></div>
<p class="paragraph"><h3 class="heading3"><a name="TutorialLesson03-ex02index.jsp%3A"> ex02-index.jsp:</a></h3>
<div class="code"><div class="codeContent">
<pre>&lt;html&gt;&#10;&lt;head&gt;&#10;&lt;title&gt;WebWork Tutorial &#45; Lesson 3 &#45; Example 2&lt;/title&gt;&#10;&lt;/head&gt;&#10;&#10;&lt;body&gt;&#10;&#10;&lt;p&gt;What&#039;s your name&#63;&lt;/p&gt;&#10;&#10;&lt;form action=<span class="java&#45;quote">&quot;hello.action&quot;</span> method=<span class="java&#45;quote">&quot;post&quot;</span>&gt;&#10;&lt;p&gt;&lt;input type=<span class="java&#45;quote">&quot;text&quot;</span> name=<span class="java&#45;quote">&quot;person&quot;</span> /&gt;&lt;input type=<span class="java&#45;quote">&quot;submit&quot;</span> /&gt;&lt;/p&gt;&#10;&lt;/form&gt;&#10;&#10;&lt;/body&gt;&#10;&lt;/html&gt;</pre>
</div></div></p><h3 class="heading3"><a name="TutorialLesson03-ex02success.jsp%3A"> ex02-success.jsp:</a></h3>
<div class="code"><div class="codeContent">
<pre>&lt;&#37;&#64; taglib uri=<span class="java&#45;quote">&quot;webwork&quot;</span> prefix=<span class="java&#45;quote">&quot;ww&quot;</span> &#37;&gt;&#10;&lt;html&gt;&#10;&lt;head&gt;&#10;&lt;title&gt;WebWork Tutorial &#45; Lesson 3 &#45; Example 2&lt;/title&gt;&#10;&lt;/head&gt;&#10;&lt;body&gt;&#10;&#10;Hello, &lt;ww:property value=<span class="java&#45;quote">&quot;person&quot;</span> /&gt;&#10;&#10;&lt;/body&gt;&#10;&lt;/html&gt;</pre>
</div></div><p class="paragraph">Let&#039;s analyse the differences: in this example we are sending form data via POST, under the name of <tt class="monospaced">person</tt>. Because of that, after a new instance of <tt class="monospaced">HelloAction</tt> is created, WebWork&#039;s <tt class="monospaced">ServletDispatcher</tt> will try to fill the action&#039;s property <tt class="monospaced">person</tt> with the data that was sent, therefore calling the mutator method <tt class="monospaced">setPerson()</tt> (actually, that is done by the <tt class="monospaced">ParametersInterceptor</tt>, which we will only learn about later, in <a href="TutorialLesson05.html" title="TutorialLesson05">lesson 5</a> &#8211; for now, know that when the action is executed, the property is already set).</p>If you look at the action class&#039; code, you will see that during <tt class="monospaced">execute()</tt>, it checks if the property was filled (i.e. if data was supplied in the form field). If it was, it returns <tt class="monospaced">SUCCESS</tt>, therefore dispatching the request to <tt class="monospaced">ex02-success.jsp</tt>, otherwise, it returns <tt class="monospaced">ERROR</tt>, moving back to <tt class="monospaced">ex02-index.jsp</tt>.<br/>

<blockquote class="blockquote"> <a href="TutorialExamples.html" title="TutorialExamples">Try the example!</a></blockquote>
<p class="paragraph"><h2 class="heading2"><a name="TutorialLesson03-TypesofResult"> Types of Result</a></h2></p>On the examples above, when we say that a result is of type <tt class="monospaced">&quot;dispatcher&quot;</tt> it means that WebWork looks for a <tt class="monospaced">result-type</tt> called <tt class="monospaced">dispatcher</tt> and finds out which result class implements it. An instance of that class is activated whenever the action returns that type of result.<p class="paragraph">Result classes are implement the <tt class="monospaced">com.opensymphony.xwork.Result</tt> interface. WebWork comes with some result classes already implemented, but you can build your own, if you want. WebWork&#039;s result types are already configured in <tt class="monospaced">webwork-default.xml</tt>:</p><ul class="star">
<li> <b class="strong">dispatcher</b> (<tt class="monospaced">com.opensymphony.webwork.dispatcher.ServletDispatcherResult</tt>): forwards the result to the specified location;</li>
</ul>
<ul class="star">
<li> <b class="strong">redirect</b> (<tt class="monospaced">com.opensymphony.webwork.dispatcher.ServletRedirectResult</tt>): redirects the result to the specified location. Unlike the dispatcher, the redirection does not send form data (via POST or GET) to the specified page;</li>
</ul>
<ul class="star">
<li> <b class="strong">velocity</b> (<tt class="monospaced">com.opensymphony.webwork.dispatcher.VelocityResult</tt>): uses a Velocity template as the result. You could use the dispatcher to forward results to Velocity pages if you have <tt class="monospaced">VelocityServlet</tt> configured in <tt class="monospaced">web.xml</tt>, but using the Velocity result is a better approach. More on Velocity on <a href="TutorialLesson04-02.html" title="TutorialLesson04-02">lesson 4.2</a>;</li>
</ul>
<ul class="star">
<li> <b class="strong">chain</b> (<tt class="monospaced">com.opensymphony.xwork.ActionChainResult</tt>): chains an action on another, i.e., the result of an action is another action;</li>
</ul>
<ul class="star">
<li> <b class="strong">xslt</b> (<tt class="monospaced">com.opensymphony.webwork.views.xslt.XSLTResult</tt>): uses an XML document transformed by an XSLT style sheet as the result.</li>
</ul><br/>
<blockquote class="blockquote"> Read more: <a href="Result Types.html" title="Result Types">Result Types</a></blockquote>
<p class="paragraph"><h2 class="heading2"><a name="TutorialLesson03-Movingon"> Moving on</a></h2></p>These examples illustrate the main concept of actions and results: they are units of execution that respond to requests, do some processing and, depending on the result, dispatch the request to some other location. Although that might seem very simple, it&#039;s just the core of WebWork&#039;s functionality. <p class="paragraph">Here are some other things that can be done with actions, just so you know what WebWork can do before we move on to other lessons:</p><ul class="star">
<li> With interceptors, it can log every action execution an even clock the execution time (<a href="TutorialLesson05.html" title="TutorialLesson05">lesson 5</a>);</li>
</ul>
<ul class="star">
<li> The action could work directly with your business object by implementing the ModelDriven interface;</li>
</ul>
<ul class="star">
<li> With XML files, configure the validation of the data that is sent to the action. If some data is not valid according to your specification, the action is not executed and error messages are attached to the action (reference: <a href="Validation.html" title="Validation">Validation</a>);</li>
</ul>
<ul class="star">
<li> By using WebWork UI Tags in association with the validation framework, forms will automatically display error messages due to invalid data input (<a href="TutorialLesson04-01-01.html" title="TutorialLesson04-01-01">lesson 4.1.1</a>);</li>
</ul>
<ul class="star">
<li> WebWork can provide to some actions instances of components (in different scopes) automatically, allowing Inversion of Control (reference: <span class="error">&#91;Inversion of Control &amp; Components&#93;</span>);</li>
</ul><br/>
The next lessons will talk about the different types of views that can be used by WebWork.<p class="paragraph"><hr class="line"/></p><a href="TutorialLesson02.html" title="TutorialLesson02">Previous Lesson</a> | <a href="TutorialLesson04.html" title="TutorialLesson04">Next Lesson</a><br/>



				    
                    			    </td>
		    </tr>
	    </table>
	    <table border="0" cellpadding="0" cellspacing="0" width="100%">
			<tr>
				<td height="12" background="border/border_bottom.gif"><img src="border/spacer.gif" width="1" height="1" border="0"/></td>
			</tr>
		    <tr>
			    <td align="center"><font color="grey">Document generated by Confluence on Oct 18, 2004 00:08</font></td>
		    </tr>
	    </table>
    </body>
</html>