blob: c29e5bcdedc26132edec0b821a9992b12186d3e5 [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>Annotations</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="/css/syntax.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>
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
/* We explicitly disable cookie tracking to avoid privacy issues */
_paq.push(['disableCookies']);
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="//analytics.apache.org/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '41']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
</head>
<body>
<a href="https://github.com/apache/struts" class="github-ribbon">
<img decoding="async" loading="lazy" style="position: absolute; right: 0; border: 0;" width="149" height="149" src="https://github.blog/wp-content/uploads/2008/12/forkme_right_red_aa0000.png?resize=149%2C149" class="attachment-full size-full" alt="Fork me on GitHub" data-recalc-dims="1">
</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-2023.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>
<li><a href="https://privacy.apache.org/policies/privacy-policy-public.html">Privacy Policy</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><a href="/commercial-support.html">Commercial Support</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 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="/contributors/">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/getting-started/annotations.md" title="Edit this page on GitHub">Edit on GitHub</a>
<a href="index.html" title="back to Getting started"><< back to Getting started</a>
<h1 class="no_toc" id="annotations">Annotations</h1>
<ul id="markdown-toc">
<li><a href="#introduction" id="markdown-toc-introduction">Introduction</a></li>
<li><a href="#struts-2-convention-plugin" id="markdown-toc-struts-2-convention-plugin">Struts 2 Convention Plugin</a></li>
<li><a href="#struts-2-configuration-plugin" id="markdown-toc-struts-2-configuration-plugin">Struts 2 Configuration Plugin</a></li>
<li><a href="#annotations-1" id="markdown-toc-annotations-1">Annotations</a></li>
<li><a href="#struts-2-configuration-values" id="markdown-toc-struts-2-configuration-values">Struts 2 Configuration Values</a></li>
<li><a href="#summary" id="markdown-toc-summary">Summary</a></li>
</ul>
<p>The example code for this tutorial, <strong>annotations</strong>, is available for checkout at <a href="https://github.com/apache/struts-examples">struts-examples</a></p>
<h2 id="introduction">Introduction</h2>
<p>In our previous tutorials we’ve been using an XML file (<code class="language-plaintext highlighter-rouge">struts.xml</code>) to configure our applications. The XML file wires
up the action names (register), with ActionSupport classes (<code class="language-plaintext highlighter-rouge">RegisterAction.java</code>), and with the result to render back
to the browser (<code class="language-plaintext highlighter-rouge">register.jsp</code>). Struts 2 provides an alternative to using XML to configure your application by using
standard naming conventions and annotations for your action names, <code class="language-plaintext highlighter-rouge">ActionSupport</code> classes, and results.</p>
<p>This tutorial assumes you understand how to apply annotations to Java classes and methods. If you’re not familiar with
annotations, consult the <a href="http://download.oracle.com/javase/tutorial/java/javaOO/annotations">Java online tutorial</a>.</p>
<p>The <a href="http://struts.apache.org/mail">Struts 2 user mailing list</a> is an excellent place to get help. If you are having
a problem getting the tutorial example applications to work search the Struts 2 mailing list. If you don’t find an answer
to your problem, post a question on the mailing list.</p>
<h2 id="struts-2-convention-plugin">Struts 2 Convention Plugin</h2>
<p>Struts 2 enables the use of standard naming conventions and annotations when you include the Convention plugin in your
application’s class path. If you’re using Maven you’ll need to add a dependency:</p>
<p><strong>Convention Plugin Dependency</strong></p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;dependency&gt;</span>
<span class="nt">&lt;groupId&gt;</span>org.apache.struts<span class="nt">&lt;/groupId&gt;</span>
<span class="nt">&lt;artifactId&gt;</span>struts2-convention-plugin<span class="nt">&lt;/artifactId&gt;</span>
<span class="nt">&lt;version&gt;</span>X.X.X.X<span class="nt">&lt;/version&gt;</span>
<span class="nt">&lt;/dependency&gt;</span>
</code></pre></div></div>
<p>If you’re using Ant then copy the struts2-convention-plugin jar file from the Struts 2 download to your <code class="language-plaintext highlighter-rouge">WEB-INF/lib</code> folder.</p>
<p>The convention plugin provide several different ways you can configure your Struts 2 application without using XML.
Consult the <a href="../plugins/convention/">Convention Plugin</a> documentation for complete details. This tutorial only examines
one simple way of following the conventions provided by the Convention plugin.</p>
<p>When you run the example application you’ll see on the <code class="language-plaintext highlighter-rouge">index.jsp</code> page a link to Get your hello. This URL for the link
is <code class="language-plaintext highlighter-rouge">hello.action</code>. When you click on this link, the execute method of class <code class="language-plaintext highlighter-rouge">HelloAction.java</code> (which is a Struts 2 <code class="language-plaintext highlighter-rouge">ActionSupport</code> class)
is run. The view page rendered back to the browser after the execute method returns success is <code class="language-plaintext highlighter-rouge">hello-success.jsp</code>.</p>
<p>None of the above is wired up using XML but rather happens because the application follows the standard naming conventions
expected by the Convention plugin. The first convention is that the ActionSupport class, <code class="language-plaintext highlighter-rouge">HelloAction.java</code>, is in package
<code class="language-plaintext highlighter-rouge">org.apache.struts.struts2annotations.action</code>. One of the Convention plugin’s defaults is to look for <code class="language-plaintext highlighter-rouge">ActionSupport</code>
classes that are in package structure that ends in action. The next convention the application follows is that <code class="language-plaintext highlighter-rouge">HelloAction.java</code>
extends the ActionSupport class and defines an execute method. The link is hello.action. When the Struts 2 filter sees
a request for hello.action it will map that request to the HelloAction class’s execute method due to the Convention
plugin being used.</p>
<p>So a link of hello.action causes the execute method of class HelloAction to be run. That method returns <code class="language-plaintext highlighter-rouge">success</code>.
Because the application is using the Convention plugin, Struts 2 will render back to the browser a view page named
<code class="language-plaintext highlighter-rouge">hello-success.jsp</code> that is located in WEB-INF/content (by default the Convention plugin expects all view pages to be
in this location). If the execute method returns “input” or “error” then the view page rendered would have been
<code class="language-plaintext highlighter-rouge">hello-input.jsp</code> or <code class="language-plaintext highlighter-rouge">hello-error.jsp</code>.</p>
<h2 id="struts-2-configuration-plugin">Struts 2 Configuration Plugin</h2>
<p>In a <a href="debugging-struts">previous tutorial</a> we reviewed how to use the Struts 2 Configuration plugin to view the details
of how Struts 2 has configured your application. When using the Convention plugin, it’s very handy to also use
the Configuration plugin during development. On the example application’s home page is a link to the application’s configuration.
Click on that link and then the hello link on the left menu (under Actions in default). You’ll see the configuration
for the hello action including it’s Action class, result, and view page.</p>
<p><img src="attachments/att24346643_Screen shot 2010-10-24 at 10.51.45 AM.png" alt="Screen shot 2010-10-24 at 10.51.45 AM.png" /></p>
<h2 id="annotations-1">Annotations</h2>
<p>If you want to go beyond the simple naming conventions provided by the Convention plugin, you can use the Struts 2
annotations also provided by the plugin. For example, a common work-flow for a Struts 2 application is to first execute
the ActionSupport class’s input method to setup form field default values and then to run the execute method of the same
ActionSupport class when the form is submitted (to validate and save the user’s input).</p>
<p>The link to Register for the drawing on the example application’s home page follows this work flow. The link value
is <code class="language-plaintext highlighter-rouge">register-input.action</code>. If you examine the RegisterAction.java class you’ll find the input method with an Action annotation.</p>
<p><strong>Action Annotation</strong></p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Action</span><span class="o">(</span><span class="s">"register-input"</span><span class="o">)</span>
<span class="kd">public</span> <span class="nc">String</span> <span class="nf">input</span><span class="o">()</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span>
<span class="n">logger</span><span class="o">.</span><span class="na">info</span><span class="o">(</span><span class="s">"In input method of class Register"</span><span class="o">);</span>
<span class="k">return</span> <span class="no">INPUT</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>
<p>The Action annotation tells Struts 2 to execute the annotated method when the action link value equals the Action
annotation’s value (<code class="language-plaintext highlighter-rouge">register-input</code>). So a link of <code class="language-plaintext highlighter-rouge">register-input.action</code> will call the input method of class <code class="language-plaintext highlighter-rouge">RegisterAction</code>.
On the example application’s home page is a link to Register for the drawing with a URL of <code class="language-plaintext highlighter-rouge">register-input.action</code>.</p>
<p>The input method above returns “input”. By the standards of the Convention plugin, the view page rendered will be
<code class="language-plaintext highlighter-rouge">register-input.jsp</code> (from <code class="language-plaintext highlighter-rouge">WEB-INF/content</code>). On that view page is a Struts 2 form tag with an action attribute value
of register. When submitting the form, the execute method of class RegisterAction will be run. Since the execute method
returns success, the view page rendered is <code class="language-plaintext highlighter-rouge">register-success.jsp</code>.</p>
<h2 id="struts-2-configuration-values">Struts 2 Configuration Values</h2>
<p>In previous examples, we included in <code class="language-plaintext highlighter-rouge">struts.xml</code> values for some of the Struts 2 configuration parameters.</p>
<p><strong>struts.xml parameter configuration</strong></p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;constant</span> <span class="na">name=</span><span class="s">"struts.devMode"</span> <span class="na">value=</span><span class="s">"true"</span> <span class="nt">/&gt;</span>
</code></pre></div></div>
<p>When we don’t use a struts.xml file, we can set the value of these Struts 2 parameters by using filter parameters in <code class="language-plaintext highlighter-rouge">web.xml</code>:</p>
<p><strong>Struts 2 Parameter Configuration web.xml</strong></p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;filter&gt;</span>
<span class="nt">&lt;filter-name&gt;</span>struts2<span class="nt">&lt;/filter-name&gt;</span>
<span class="nt">&lt;filter-class&gt;</span>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter<span class="nt">&lt;/filter-class&gt;</span>
<span class="nt">&lt;init-param&gt;</span>
<span class="nt">&lt;param-name&gt;</span>struts.devMode<span class="nt">&lt;/param-name&gt;</span>
<span class="nt">&lt;param-value&gt;</span>true<span class="nt">&lt;/param-value&gt;</span>
<span class="nt">&lt;/init-param&gt;</span>
<span class="nt">&lt;/filter&gt;</span>
</code></pre></div></div>
<h2 id="summary">Summary</h2>
<p>We’ve just scratched the surface of what the Struts 2 convention plugin provides to reduce or eliminate the need to use
an XML file to configure your Struts 2 application. The Struts 2 Convention plugin provides ways to map multiple actions
to the same method, map results to different view pages, map errors to view pages, and much more. Be sure to read through
the <a href="../plugins/convention/">Convention Plugin</a> documentation for alternative ways to configure your Struts 2 application.</p>
<table>
<tbody>
<tr>
<td>Return to <a href="spring">Spring and Struts 2</a></td>
<td>or</td>
<td>onward to <a href="introducing-interceptors">Introducing Interceptors</a></td>
</tr>
</tbody>
</table>
</section>
</article>
<footer class="container">
<div class="col-md-12">
Copyright &copy; 2000-2022 <a href="https://www.apache.org/">The Apache Software Foundation</a>.
Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts project logos are
trademarks of The Apache Software Foundation. All Rights Reserved.
</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>