| <html><head> |
| <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
| <title>2.7. Page Actions</title><link rel="stylesheet" href="css/stylesheet.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.75.0"><link rel="home" href="index.html" title="Apache Click"><link rel="up" href="ch02.html" title="Chapter 2. Pages"><link rel="prev" href="ch02s06.html" title="2.6. Page Templating"><link rel="next" href="ch02s08.html" title="2.8. Direct Rendering"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">2.7. Page Actions</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch02s06.html">Prev</a> </td><th width="60%" align="center">Chapter 2. Pages</th><td width="20%" align="right"> <a accesskey="n" href="ch02s08.html">Next</a></td></tr></table><hr></div><div class="sect1" title="2.7. Page Actions"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="page-actions"></a>2.7. Page Actions</h2></div></div></div><p>Page Action is a feature to directly invoke a <code class="literal">Page method</code> |
| from the browser. The Page Action method returns an |
| <a xmlns:fo="http://www.w3.org/1999/XSL/Format" class="external" href="../../click-api/org/apache/click/ActionResult.html" target="_blank">ActionResult</a> |
| object that is rendered directly to the browser. In other words the Page template will |
| not be rendered. |
| </p><p>To invoke a Page Action, specify the parameter <code class="varname">"pageAction"</code> |
| and the name of the page method, for example: <span class="symbol">"onRenderImage"</span>. |
| </p><p>Let's take a quick look at how a Page Action can be leveraged to retrieve |
| an image. In this example we'll create an HTML <code class="literal"><img></code> |
| element which <code class="literal">src</code> attribute specifies the Page Action |
| that will return the image data. |
| </p><p>First we create our template: |
| </p><pre class="programlisting"><span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="tag"><img</span> <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="atn">src</span>=<span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="pln">"$context/mycorp/image.htm?</span><code class="varname">pageAction</code>=<span class="symbol">onRenderImage</span>"/> |
| </pre><p>Next we create our ImagePage with a Page Action method called |
| <span class="symbol">onRenderImage</span> that returns an <span class="token">ActionResult</span> |
| instance: |
| </p><pre class="programlisting"><span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">public</span> <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">class</span> ImagePage <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">extends</span> Page { |
| |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">public</span> <span class="token">ActionResult</span> <span class="symbol">onRenderImage()</span> { |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">byte</span>[] imageData = getImageAsBytes(); |
| String contentType = ClickUtils.getMimeType(<span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="str">"png"</span>); |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">return</span> <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">new</span> <span class="token">ActionResult</span>(imageData, contentType); |
| } |
| } </pre><p>A Page Action is a normal Page method with the following signature: |
| a <span class="symbol">public no-arg</span> method returning an <span class="token">ActionResult</span> |
| instance: |
| </p><pre class="programlisting"> |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="com">// The Page Action method is public, doesn't accept any arguments and returns an ActionResult</span> |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">public</span> <span class="token">ActionResult</span> <span class="symbol">onRenderImage()</span> { |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">byte</span>[] imageData = getImageAsBytes(); |
| String contentType = ClickUtils.getMimeType(<span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="str">"png"</span>); |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">return</span> <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">new</span> <span class="token">ActionResult</span>(imageData, contentType); |
| } </pre><p>The <span class="token">ActionResult</span> contains the data that is rendered to |
| the client browser. In the example above, the result will the Image byte array |
| with a Content-Type of: <code class="literal">"images/png"</code>. |
| </p><div class="sect2" title="2.7.1. Page Action Execution"><div class="titlepage"><div><div><h3 class="title"><a name="page-action-execution"></a>2.7.1. Page Action Execution</h3></div></div></div><p>Page Actions are page methods that handle the processing of a user |
| request and render a result to the browser. The execution sequence for a |
| Page Action being processed and rendered is illustrated in the figure below. |
| </p><div class="figure"><a name="page-action-sequence-diagram"></a><div class="figure-contents"><span class="inlinemediaobject"><img src="images/pages/page-action-sequence-diagram.png" alt="Page Action Request Sequence Diagram"></span></div><p xmlns:fo="http://www.w3.org/1999/XSL/Format" class="title"><i>Figure 2.5. Page Action Request Sequence Diagram |
| </i></p></div><br class="figure-break"><p>Stepping through this Page Action request sequence, a new Page instance |
| is created and the attributes for the Page are set (format, headers). Next, |
| request parameter values are bound to matching Page fields. |
| </p><p>Then the <code class="methodname">onSecurityCheck()</code> handler is executed. |
| This method can be used to ensure the user is authorized to access the Page Action, |
| and if necessary abort any further processing. If |
| <code class="methodname">onSecurityCheck()</code> return false, no response is |
| sent back to the client. Note, if you want to send a specific response to |
| the client you have to do that from the |
| <code class="methodname">onSecurityCheck()</code> event, since other Page events |
| are not executed. Please see |
| <a xmlns:fo="http://www.w3.org/1999/XSL/Format" class="external" href="http://click.avoka.com/click-examples/ajax/ajax-secure.htm" target="_blank">this</a> |
| example for some strategies on implementing |
| <code class="methodname">onSecurityCheck</code> to handle ajax requests. |
| </p><p>Next the target <code class="methodname">page method</code> is invoked |
| which returns an <code class="classname">ActionResult</code> that is rendered to |
| the client.</p><p>If the page method returns <code class="literal">null</code> no response is |
| rendered to the browser. |
| </p></div><div class="sect2" title="2.7.2. ActionResult"><div class="titlepage"><div><div><h3 class="title"><a name="page-action-result"></a>2.7.2. ActionResult</h3></div></div></div><p>An ActionResult represents the content returned by a Page Action |
| which is then rendered to the client browser. ActionResults normally |
| contains HTML or image data that is rendered to the browser. When a Page |
| Action is invoked the Page template rendering is bypassed and only the |
| ActionResult content is rendered to the browser. This allows a Page Action |
| to return a "partial" response, as opposed to a "full" response, because |
| the Page template (which can be viewed as a "full" response) is bypassed |
| when invoking a Page Action. |
| </p></div><div class="sect2" title="2.7.3. Page Action Example"><div class="titlepage"><div><div><h3 class="title"><a name="page-action-example"></a>2.7.3. Page Action Example</h3></div></div></div><p>Let's step through a Page Action example. First we create an ImagePage |
| class with the method "getImageData" which is the Page Action we want to invoke: |
| </p><pre class="programlisting"><span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">public</span> ImagePage <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">extends</span> Page { |
| |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">public</span> ActionResult getImageData() { |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">byte</span>[] imageData = loadImageData(); |
| String contentType = ClickUtils.getContentType(<span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="str">"png"</span>); |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">return</span> <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">new</span> ActionResult(imageData, contentType); |
| } |
| } </pre><p>Next we have the page template image.htm: |
| </p><pre class="programlisting"><span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="tag"><html></span> |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="tag"><body></span> |
| |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="tag"><img</span> <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="atn">src</span>=<span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="pln">"/mycorp/image.htm?</span><code class="varname">pageAction</code>=<span class="symbol">getImageData</span>"/> |
| |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="tag"></body></span> |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="tag"></html></span> </pre><p>The browser renders the <code class="literal"><img></code> element and |
| requests the image src url. Click invokes the page method <span class="symbol">getImageData</span> |
| and renders the result to the browser. |
| </p><p>Looking at the output log we see the following trace: |
| </p><div class="literallayout"><p>[Click] [info ] handleRequest: /image.htm - 84 ms<br> |
| [Click] [debug] GET http://localhost:8080/mycorp/image.htm<br> |
| [Click] [trace] is Ajax request: false<br> |
| [Click] [trace] request param: pageAction=getImageData<br> |
| [Click] [trace] invoked: ImagePage.<<init>><br> |
| [Click] [trace] invoked: ImagePage.onSecurityCheck() : true<br> |
| [Click] [trace] invoked: ImagePage.getImageData() : ActionResult<br> |
| [Click] [info ] renderActionResult (image/png) - 0 ms<br> |
| [Click] [trace] invoked: ImagePage.onDestroy()<br> |
| [Click] [info ] handleRequest: /image.htm - 98 ms</p></div></div><div class="sect2" title="2.7.4. Accessing Request Parameters"><div class="titlepage"><div><div><h3 class="title"><a name="page-action-accessing-request-parameters"></a>2.7.4. Accessing Request Parameters</h3></div></div></div><p>Request parameters can be accessed through the <code class="classname">Context</code> |
| as shown below: |
| </p><pre class="programlisting"><span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">public</span> ImagePage <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">extends</span> Page { |
| |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">public</span> ActionResult getImageData() { |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="com">// Retrieve a request parameter through the Context</span> |
| Context context = getContext(); |
| String imageName = context.getRequestParameter(<span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="str">"imageName"</span>); |
| |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">byte</span>[] imageData = loadImageData(imageName); |
| String contentType = ClickUtils.getContentType(<span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="str">"png"</span>); |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">return</span> <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">new</span> ActionResult(imageData, contentType); |
| } |
| } </pre></div><div class="sect2" title="2.7.5. Set response headers and status code"><div class="titlepage"><div><div><h3 class="title"><a name="page-action-set-response-headers"></a>2.7.5. Set response headers and status code</h3></div></div></div><p>When handling a Page Action you might need to set the HTTP response |
| headers or status code. You do this through the Servlet API's, |
| <code class="classname">HttpServetlResponse</code> which can be accessed |
| through the <code class="classname">Context</code>. |
| </p><p>For example: |
| </p><pre class="programlisting"><span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">package</span> examples.page; |
| |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">import</span> java.util.Date; |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">import</span> org.apache.click.Page; |
| |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">public</span> ImagePage <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">extends</span> Page { |
| |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="kwd">public</span> ActionResult getImageData() { |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="com">// Headers and Status code are set on the HttpServletResponse</span> |
| HttpServletResponse response = getContext().getResponse(); |
| |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="com">// The headers can be set as follows:</span> |
| response.setHeader(<span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="str">"Content-Disposition"</span>, <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="str">"attachment; filename=\"report.xls\""</span>); |
| |
| ... |
| |
| <span xmlns:fo="http://www.w3.org/1999/XSL/Format" class="com">// The response status can be set as follows:</span> |
| response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); |
| |
| ... |
| } |
| } </pre></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch02s06.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ch02.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ch02s08.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">2.6. Page Templating </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 2.8. Direct Rendering</td></tr></table></div></body></html> |