blob: 5b91f48579426e4e39c6809535c716b16c7ebfa7 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="Date-Revision-yyyymmdd" content="20140918"/>
<meta http-equiv="Content-Language" content="en"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Access to ValueStack from JSPs</title>
<link href="//fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,400italic,600italic,700italic" rel="stylesheet" type="text/css">
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
<link href="/css/main.css" rel="stylesheet">
<link href="/css/custom.css" rel="stylesheet">
<link href="/highlighter/github-theme.css" rel="stylesheet">
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="/bootstrap/js/bootstrap.js"></script>
<script type="text/javascript" src="/js/community.js"></script>
</head>
<body>
<a href="http://github.com/apache/struts" class="github-ribbon">
<img style="position: absolute; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png" alt="Fork me on GitHub">
</a>
<header>
<nav>
<div role="navigation" class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" data-toggle="collapse" data-target="#struts-menu" class="navbar-toggle">
Menu
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a href="/index.html" class="navbar-brand logo"><img src="/img/struts-logo.svg"></a>
</div>
<div id="struts-menu" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="dropdown">
<a data-toggle="dropdown" href="#" class="dropdown-toggle">
Home<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><a href="/index.html">Welcome</a></li>
<li><a href="/download.cgi">Download</a></li>
<li><a href="/releases.html">Releases</a></li>
<li><a href="/announce-2021.html">Announcements</a></li>
<li><a href="http://www.apache.org/licenses/">License</a></li>
<li><a href="https://www.apache.org/foundation/thanks.html">Thanks!</a></li>
<li><a href="https://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li>
</ul>
</li>
<li class="dropdown">
<a data-toggle="dropdown" href="#" class="dropdown-toggle">
Support<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><a href="/mail.html">User Mailing List</a></li>
<li><a href="https://issues.apache.org/jira/browse/WW">Issue Tracker</a></li>
<li><a href="/security.html">Reporting Security Issues</a></li>
<li class="divider"></li>
<li><a href="https://cwiki.apache.org/confluence/display/WW/Migration+Guide">Version Notes</a></li>
<li><a href="https://cwiki.apache.org/confluence/display/WW/Security+Bulletins">Security Bulletins</a></li>
<li class="divider"></li>
<li><a href="/maven/project-info.html">Maven Project Info</a></li>
<li><a href="/maven/struts2-core/dependencies.html">Struts Core Dependencies</a></li>
<li><a href="/maven/struts2-plugins/modules.html">Plugin Dependencies</a></li>
</ul>
</li>
<li class="dropdown">
<a data-toggle="dropdown" href="#" class="dropdown-toggle">
Documentation<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><a href="/birdseye.html">Birds Eye</a></li>
<li><a href="/primer.html">Key Technologies</a></li>
<li><a href="/kickstart.html">Kickstart FAQ</a></li>
<li><a href="https://cwiki.apache.org/confluence/display/WW/Home">Wiki</a></li>
<li class="divider"></li>
<li><a href="/getting-started/">Getting Started</a></li>
<li><a href="/security/">Security Guide</a></li>
<li><a href="/core-developers/">Core Developers Guide</a></li>
<li><a href="/tag-developers/">Tag Developers Guide</a></li>
<li><a href="/maven-archetypes/">Maven Archetypes</a></li>
<li><a href="/plugins/">Plugins</a></li>
<li><a href="/maven/struts2-core/apidocs/index.html">Struts Core API</a></li>
<li><a href="/tag-developers/tag-reference.html">Tag reference</a></li>
<li><a href="https://cwiki.apache.org/confluence/display/WW/FAQs">FAQs</a></li>
<li><a href="http://cwiki.apache.org/S2PLUGINS/home.html">Plugin registry</a></li>
</ul>
</li>
<li class="dropdown">
<a data-toggle="dropdown" href="#" class="dropdown-toggle">
Contributing<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><a href="/youatstruts.html">You at Struts</a></li>
<li><a href="/helping.html">How to Help FAQ</a></li>
<li><a href="/dev-mail.html">Development Lists</a></li>
<li><a href="/contributors/">Contributors Guide</a></li>
<li class="divider"></li>
<li><a href="/submitting-patches.html">Submitting patches</a></li>
<li><a href="/builds.html">Source Code and Builds</a></li>
<li><a href="/coding-standards.html">Coding standards</a></li>
<li><a href="https://cwiki.apache.org/confluence/display/WW/Contributors+Guide">Contributors Guide</a></li>
<li class="divider"></li>
<li><a href="/release-guidelines.html">Release Guidelines</a></li>
<li><a href="/bylaws.html">PMC Charter</a></li>
<li><a href="/volunteers.html">Volunteers</a></li>
<li><a href="https://gitbox.apache.org/repos/asf?p=struts.git">Source Repository</a></li>
<li><a href="/updating-website.html">Updating the website</a></li>
</ul>
</li>
<li class="apache"><a href="http://www.apache.org/"><img src="/img/apache.png"></a></li>
</ul>
</div>
</div>
</div>
</nav>
</header>
<article class="container">
<section class="col-md-12">
<a class="edit-on-gh" href="https://github.com/apache/struts-site/edit/master/source/tag-developers/access-to-valuestack-from-jsps.md" title="Edit this page on GitHub">Edit on GitHub</a>
<h1 id="access-to-valuestack-from-jsps">Access to ValueStack from JSPs</h1>
<p>To access the ValueStack from third-party JSP taglibs, expose property values to JSP using the <code class="highlighter-rouge">&lt;s:set/&gt;</code> tag.</p>
<p><strong>Set a request scoped parameter ‘a’ to list of integers</strong></p>
<pre><code class="language-jsp">&lt;s:set name="'a'" value="{ 1, 2, 3, 4 }" scope="request"/&gt;
</code></pre>
<p>After setting parameters, third-party JSP taglibs can access variables or use JSP 2.0 EL (Expression Language).
This is convenient as short hand EL expression syntax <code class="highlighter-rouge">${expression}</code> can be used in a text or inside of tag attributes:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>a[0] = ${a[0]}
&lt;sample:tag value="${a[1]}"/&gt;
</code></pre></div></div>
<p>In practice, several variables must be exposed to make effective use of third party taglibs like <a href="http://displaytag.sourceforge.net/11/">DisplayTag</a>.
Unfortunately, this approach leads to a lot of <code class="highlighter-rouge">&lt;s:set/&gt;</code> tags.</p>
<blockquote>
<p>Unfortunately, it isn’t that simple. we tinkered with <code class="highlighter-rouge">JSPFactory.setDefault()</code> to wrap around <code class="highlighter-rouge">getPageContext()</code>
and create <code class="highlighter-rouge">ExpressionEvaluator</code> that would use OGNL. This strategy works in practice, but code generated by Jasper2
doesn’t call <code class="highlighter-rouge">JSPFactory.getPageContext().getExpressionEvaluator()</code> but goes directly to static method that is
hardwired to Jakarta Commons-EL implementation.</p>
</blockquote>
<blockquote>
<table>
<tbody>
<tr>
<td>Even if this approach did work, it wouldn’t be <em>clean</em> as <code class="highlighter-rouge">JSPFactory.setDefault()</code> should only be called by JSP implementation.</td>
</tr>
</tbody>
</table>
</blockquote>
<p>There is a simple, if not elegant, solution available in JSP 2.0 EL, for exposing ValueStack to OGNL. It is possible
to create custom functions that can be called from EL expressions. Functions have to be ‘public static’ and specified
in a TLD file.</p>
<p>To use a function, import the TLD in a JSP file where you’ve want to use a function. For example, you could access
Action properties by evaluating OGNL expression by a function ‘vs’ (for valuestack) in EL.</p>
<pre><code class="language-jsp">&lt;%@ taglib uri="/WEB-INF/tld/wwel.tld" prefix="x" %&gt;
a[0] = ${x:vs('a[0]')}
a[0] * 4 = ${x:vs('a[0] * 4')}
Current action name: ${x:name()}
Top of ValueStack: ${x:top()}
</code></pre>
<p>To use this code you’ve got to add <code class="highlighter-rouge">wwel.tld</code> and <code class="highlighter-rouge">Functions.java</code> to your webapp project.</p>
<blockquote>
<p>If someone were interested, it would be helpful for a developer (like you!) to define a set of functions that we could
include in a future release of the framework.</p>
</blockquote>
<p><strong>wwel.tld</strong></p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?xml version="1.0"?&gt;</span>
<span class="nt">&lt;taglib</span> <span class="na">xmlns=</span><span class="s">"http://java.sun.com/xml/ns/j2ee"</span>
<span class="na">xmlns:xsi=</span><span class="s">"http://www.w3.org/2001/XMLSchema-instance"</span>
<span class="na">xsi:schemaLocation=</span><span class="s">"http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"</span>
<span class="na">version=</span><span class="s">"2.0"</span><span class="nt">&gt;</span>
<span class="nt">&lt;description&gt;</span>
This taglib enables access to the ValueStack
from JSP 2.0 Expression Language
<span class="nt">&lt;/description&gt;</span>
<span class="nt">&lt;tlib-version&gt;</span>1.0<span class="nt">&lt;/tlib-version&gt;</span>
<span class="nt">&lt;short-name&gt;</span>wwel<span class="nt">&lt;/short-name&gt;</span>
<span class="nt">&lt;function&gt;</span>
<span class="nt">&lt;name&gt;</span>vs<span class="nt">&lt;/name&gt;</span>
<span class="nt">&lt;function-class&gt;</span>com.nmote.wwel.Functions<span class="nt">&lt;/function-class&gt;</span>
<span class="nt">&lt;function-signature&gt;</span>
java.lang.Object findOnValueStack(java.lang.String)
<span class="nt">&lt;/function-signature&gt;</span>
<span class="nt">&lt;/function&gt;</span>
<span class="nt">&lt;function&gt;</span>
<span class="nt">&lt;name&gt;</span>name<span class="nt">&lt;/name&gt;</span>
<span class="nt">&lt;function-class&gt;</span>com.nmote.wwel.Functions<span class="nt">&lt;/function-class&gt;</span>
<span class="nt">&lt;function-signature&gt;</span>
java.lang.Object getActionName()
<span class="nt">&lt;/function-signature&gt;</span>
<span class="nt">&lt;/function&gt;</span>
<span class="nt">&lt;function&gt;</span>
<span class="nt">&lt;name&gt;</span>top<span class="nt">&lt;/name&gt;</span>
<span class="nt">&lt;function-class&gt;</span>com.nmote.wwel.Functions<span class="nt">&lt;/function-class&gt;</span>
<span class="nt">&lt;function-signature&gt;</span>
java.lang.Object getTopOfValueStack()
<span class="nt">&lt;/function-signature&gt;</span>
<span class="nt">&lt;/function&gt;</span>
<span class="nt">&lt;/taglib&gt;</span>
</code></pre></div></div>
<p><strong>Functions.java</strong></p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="n">com</span><span class="o">.</span><span class="na">nmote</span><span class="o">.</span><span class="na">wwel</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">com.opensymphony.xwork.ActionContext</span><span class="o">;</span>
<span class="cm">/**
* Utility functions for accessing value stack and action context
* from JSP 2.0 EL taglibs.
*/</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Functions</span> <span class="o">{</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="n">Object</span> <span class="nf">findOnValueStack</span><span class="o">(</span><span class="n">String</span> <span class="n">expr</span><span class="o">)</span> <span class="o">{</span>
<span class="n">ActionContext</span> <span class="n">a</span> <span class="o">=</span> <span class="n">ActionContext</span><span class="o">.</span><span class="na">getContext</span><span class="o">();</span>
<span class="n">Object</span> <span class="n">value</span> <span class="o">=</span> <span class="n">a</span><span class="o">.</span><span class="na">getValueStack</span><span class="o">().</span><span class="na">findValue</span><span class="o">(</span><span class="n">expr</span><span class="o">);</span>
<span class="k">return</span> <span class="n">value</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="n">Object</span> <span class="nf">getTopOfValueStack</span><span class="o">()</span> <span class="o">{</span>
<span class="n">ActionContext</span> <span class="n">a</span> <span class="o">=</span> <span class="n">ActionContext</span><span class="o">.</span><span class="na">getContext</span><span class="o">();</span>
<span class="n">Object</span> <span class="n">value</span> <span class="o">=</span> <span class="n">a</span><span class="o">.</span><span class="na">getValueStack</span><span class="o">().</span><span class="na">peek</span><span class="o">();</span>
<span class="k">return</span> <span class="n">value</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="n">Object</span> <span class="nf">getActionName</span><span class="o">()</span> <span class="o">{</span>
<span class="n">ActionContext</span> <span class="n">a</span> <span class="o">=</span> <span class="n">ActionContext</span><span class="o">.</span><span class="na">getContext</span><span class="o">();</span>
<span class="n">Object</span> <span class="n">value</span> <span class="o">=</span> <span class="n">a</span><span class="o">.</span><span class="na">getName</span><span class="o">();</span>
<span class="k">return</span> <span class="n">value</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
</section>
</article>
<footer class="container">
<div class="col-md-12">
Copyright &copy; 2000-2018 <a href="http://www.apache.org/">The Apache Software Foundation </a>.
All Rights Reserved.
</div>
<div class="col-md-12">
Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts project logos are
trademarks of The Apache Software Foundation.
</div>
<div class="col-md-12">Logo and website design donated by <a href="https://softwaremill.com/">SoftwareMill</a>.</div>
</footer>
<script>!function (d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (!d.getElementById(id)) {
js = d.createElement(s);
js.id = id;
js.src = "//platform.twitter.com/widgets.js";
fjs.parentNode.insertBefore(js, fjs);
}
}(document, "script", "twitter-wjs");</script>
<script src="https://apis.google.com/js/platform.js" async="async" defer="defer"></script>
<div id="fb-root"></div>
<script>(function (d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s);
js.id = id;
js.src = "//connect.facebook.net/en_GB/all.js#xfbml=1";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>
</body>
</html>