| <!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"><dependency></span> |
| <span class="nt"><groupId></span>org.apache.struts<span class="nt"></groupId></span> |
| <span class="nt"><artifactId></span>struts2-convention-plugin<span class="nt"></artifactId></span> |
| <span class="nt"><version></span>X.X.X.X<span class="nt"></version></span> |
| <span class="nt"></dependency></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"><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">/></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"><filter></span> |
| <span class="nt"><filter-name></span>struts2<span class="nt"></filter-name></span> |
| <span class="nt"><filter-class></span>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter<span class="nt"></filter-class></span> |
| <span class="nt"><init-param></span> |
| <span class="nt"><param-name></span>struts.devMode<span class="nt"></param-name></span> |
| <span class="nt"><param-value></span>true<span class="nt"></param-value></span> |
| <span class="nt"></init-param></span> |
| <span class="nt"></filter></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 © 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> |