blob: 98ec623b220dc8f7d7d09379b7cf221e60f64753 [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>Codebehind Plugin</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-2024.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/plugins/codebehind/index.md" title="Edit this page on GitHub">Edit on GitHub</a>
<a href="../" title="back to Plugins"><< back to Plugins</a>
<h1 class="no_toc" id="codebehind-plugin">Codebehind Plugin</h1>
<ul id="markdown-toc">
<li><a href="#features" id="markdown-toc-features">Features</a></li>
<li><a href="#usage" id="markdown-toc-usage">Usage</a> <ul>
<li><a href="#default-mappings" id="markdown-toc-default-mappings">Default Mappings</a></li>
<li><a href="#default-results" id="markdown-toc-default-results">Default Results</a></li>
<li><a href="#settings" id="markdown-toc-settings">Settings</a></li>
<li><a href="#installation" id="markdown-toc-installation">Installation</a></li>
</ul>
</li>
</ul>
<blockquote>
<p>Deprecated Plugin</p>
</blockquote>
<p>Since 2.1 this plugin has been deprecated in favor of the <a href="../convention">Convention Plugin</a>. See <a href="../convention/converting">this page</a>
for details on how to port your application to the Convention plugin.</p>
<p>The Codebehind Plugin reduces mundane configuration by adding “Page Controller” conventions.</p>
<p>There are two common situations where the plugin applies convention over configuration:</p>
<ol>
<li><strong>Default mappings</strong> - (or “pages with no mappings”) These are cases where the page is mostly static and doesn’t</li>
<li>require an Action class to execute logic. Common examples are index pages and those that heavily use JSP tags</li>
<li>
<p>or JSF components.</p>
</li>
<li><strong>Default results</strong> - The purpose of most Actions is to execute code to prepare the data for a specific page.</li>
<li>The name of this page is often the same as the Action itself.</li>
</ol>
<p>To improve the first case, the plugin will detect the presence of a page with no corresponding Struts mapping
and automatically substitute a mapping that uses the default Action class for the package, which is usually
ActionSupport, a NO-OP Action.</p>
<p>For the problem of default results, the plugin will make it unnecessary to define those results by detecting
the presence of a page for that Action and creating the appropriate configuration on-the-fly.</p>
<p>In these two ways, the plugin encourages a page-based development style, handling the linking of Struts actions
with pages and pages with Results in a common way.</p>
<blockquote>
<p>To see the plugin in action, review the “Person Manager” example in the Showcase application.</p>
</blockquote>
<h2 id="features">Features</h2>
<ul>
<li>
<p>Provides default mappings for pages that don’t have Actions</p>
</li>
<li>
<p>Provides default results by auto-discovering pages</p>
</li>
</ul>
<h2 id="usage">Usage</h2>
<p>To use this plugin, simply copy its jar into your application. The plugin can be used to find default mappings
and results.</p>
<h3 id="default-mappings">Default Mappings</h3>
<p>To better facilitate a code-behind development approach, the plugin will detect the case where the request has
no defined Struts action mapping, yet there exists a corresponding page. It will then create a dummy action mapping referencing the default Action class (usually ActionSupport), allowing the page to be displayed normally. Additionally, the default interceptor stack for the configured package will be applied, bringing the workflow benefits of interceptor stacks to simple pages.</p>
<p>When no explicitly configured Action can be found for a request, the plugin searches the web application for
a likely page. Specifically, the following pattern is used to locate a page:<code class="language-plaintext highlighter-rouge">/NAMESPACE/ACTION.(jsp|vm|ftl)</code>
For example, if the request is for <code class="language-plaintext highlighter-rouge">http://www.company.com/myapp/member/login.action</code>, the plugin will look for
the following pages, in this order:</p>
<ol>
<li><code class="language-plaintext highlighter-rouge">/member/login.jsp</code></li>
<li><code class="language-plaintext highlighter-rouge">/member/login.vm</code></li>
<li><code class="language-plaintext highlighter-rouge">/member/login.ftl</code></li>
</ol>
<p>If any of those pages are found, the plugin will construct an ActionConfig object on the fly, using the ActionSupport
class for the Action and a single Result that points to the discovered page. The ActionConfig will be put in the configured
package, meaning that it will inherit the default Interceptor stack for that package. The default package
is <code class="language-plaintext highlighter-rouge">codebehind-default</code>, however, it can be configured in any <em>configuration file</em> via the <code class="language-plaintext highlighter-rouge">struts.codebehind.defaultPackage</code>
constant.</p>
<h3 id="default-results">Default Results</h3>
<p>In many applications, a majority of Results could have the same root name as the action mapping. To reduce this
unnecessary configuration, the Struts plugin will try to guess the appropriate Result, if none is explicitly configured.
This technique works for any result code, including <code class="language-plaintext highlighter-rouge">success</code>. When combined with the <em>Zero Configuration</em> style,
the amount of configuration in an application dwindles to next to nothing.</p>
<p>When no explicitly configured Result is found for an Action’s result code, the plugin, again, searches the web
application for a matching page. Specifically, the following patterns, in the following order, are used to locate
a page:</p>
<ol>
<li><code class="language-plaintext highlighter-rouge">/NAMESPACE/ACTION-RESULT_CODE.(jsp|vm|ftl)</code></li>
<li><code class="language-plaintext highlighter-rouge">/NAMESPACE/ACTION.(jsp|vm|ftl)</code></li>
</ol>
<p>These two patterns are searched for each of the three default page extensions: jsp, vm, and ftl. For example,
if the request is for <code class="language-plaintext highlighter-rouge">http://www.company.com/myapp/member/login.action</code>, so that the action name is <code class="language-plaintext highlighter-rouge">login</code>
and the namespace is <code class="language-plaintext highlighter-rouge">member</code>, and the Action class returned a code of <code class="language-plaintext highlighter-rouge">success</code>, the plugin will look for
the following pages, in this order:</p>
<ol>
<li><code class="language-plaintext highlighter-rouge">/member/login-success.jsp</code></li>
<li><code class="language-plaintext highlighter-rouge">/member/login.jsp</code></li>
<li><code class="language-plaintext highlighter-rouge">/member/login-success.vm</code></li>
<li><code class="language-plaintext highlighter-rouge">/member/login.vm</code></li>
<li><code class="language-plaintext highlighter-rouge">/member/login-success.ftl</code></li>
<li><code class="language-plaintext highlighter-rouge">/member/login.ftl</code></li>
</ol>
<p>If any of those pages are found, the appropriate Result will be constructed and processed.</p>
<h3 id="settings">Settings</h3>
<p>The following settings can be customized. See the <a href="/core-developers/configuration-files">developer guide</a>.</p>
<table>
<thead>
<tr>
<th>Setting</th>
<th>Description</th>
<th>Default</th>
<th>Possible Values</th>
</tr>
</thead>
<tbody>
<tr>
<td>struts.codebehind.defaultPackage</td>
<td>The default package to use for created Action mappings</td>
<td>codebehind-default</td>
<td>Any existing package name</td>
</tr>
<tr>
<td>struts.configuration.classpath.disableActionScanning</td>
<td>Whether to disable scanning the classpath for Action classes or not</td>
<td>false</td>
<td>true or false</td>
</tr>
</tbody>
</table>
<h3 id="installation">Installation</h3>
<p>This plugin can be installed by copying the plugin jar into your application’s <code class="language-plaintext highlighter-rouge">/WEB-INF/lib</code> directory.<br />
No other files need to be copied or created.</p>
</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>