blob: be46c409a0b7ab4b1481206c232e33c3a888dd30 [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>Static Content</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>
<!-- 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 href="index.html" title="back to Core Developers Guide"><< back to Core Developers Guide</a>
<a class="edit-on-gh" href="https://github.com/apache/struts-site/edit/master/source/core-developers/static-content.md" title="Edit this page on GitHub">Edit on GitHub</a>
<h1 class="no_toc" id="static-content">Static Content</h1>
<ul id="markdown-toc">
<li><a href="#disabling-static-content" id="markdown-toc-disabling-static-content">Disabling static content</a></li>
<li><a href="#custom-static-content-loaders" id="markdown-toc-custom-static-content-loaders">Custom Static Content Loaders</a></li>
<li><a href="#default-content-loader" id="markdown-toc-default-content-loader">Default Content Loader</a></li>
<li><a href="#default-path" id="markdown-toc-default-path">Default path</a></li>
<li><a href="#preventing-struts-from-handling-a-request" id="markdown-toc-preventing-struts-from-handling-a-request">Preventing Struts from handling a request</a></li>
</ul>
<p>Struts can serve a static content like CSS and JavaScript files using a predefined path. By default, these resources
are served using <code class="language-plaintext highlighter-rouge">/static</code> path defined using a constant <code class="language-plaintext highlighter-rouge">struts.ui.staticContentPath</code> - see below for more details.</p>
<p>Please remember to include this path in your filter mapping if you use a custom mapping, see <a href="web-xml.md">web.xml</a> example config.</p>
<h2 id="disabling-static-content">Disabling static content</h2>
<p>You can disable this feature by setting the following constant to <code class="language-plaintext highlighter-rouge">false</code>. Once disabled you must provided the required
CSS &amp; JavaScript files on your own, which can be a good thing when you want to use a CDN.</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.serve.static"</span> <span class="na">value=</span><span class="s">"false"</span><span class="nt">/&gt;</span>
</code></pre></div></div>
<blockquote>
<p>If you disable this feature, but you use the <code class="language-plaintext highlighter-rouge">xhtml</code>, or <code class="language-plaintext highlighter-rouge">css_xhtml</code> theme, make sure the JavasScript and CSS files
shipped inside the core jar are extracted to your web application directory or served in some other way.</p>
</blockquote>
<h2 id="custom-static-content-loaders">Custom Static Content Loaders</h2>
<p>Static content is served by an implementation of <code class="language-plaintext highlighter-rouge">org.apache.struts2.dispatcher.StaticContentLoader</code>. To write your own
<code class="language-plaintext highlighter-rouge">StaticContentLoader</code>, implement <code class="language-plaintext highlighter-rouge">StaticContentLoader</code> and define a bean for the class:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;bean</span> <span class="na">type=</span><span class="s">"org.apache.struts2.dispatcher.StaticContentLoader"</span> <span class="na">class=</span><span class="s">"MyStaticContentLoader"</span> <span class="na">name=</span><span class="s">"myLoader"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;constant</span> <span class="na">name=</span><span class="s">"struts.staticContentLoader"</span> <span class="na">value=</span><span class="s">"myLoader"</span><span class="nt">/&gt;</span>
</code></pre></div></div>
<h2 id="default-content-loader">Default Content Loader</h2>
<p>The Apache Struts provides a default implementation of <code class="language-plaintext highlighter-rouge">StaticContentLoader</code> which
is <code class="language-plaintext highlighter-rouge">org.apache.struts2.dispatcher.DefaultStaticContentLoader</code>. This loader will handle urls that start with “/static/”
by default.</p>
<p>This content loader can serve static content from the classpath, so when writing a plugin, you can put a file inside
your plugin’s jar like “/static/image/banner.jpg” and it will be served when the url “/static/image/banner.jpg” is
requested.</p>
<blockquote>
<p>This loader is not optimized to handle static content, and to improve performance, it is recommended that you extract
your static content to the web application directory, and let the container handle them.</p>
</blockquote>
<h2 id="default-path">Default path</h2>
<p>If needed you can change the default path at which static content is served. Just define a new <code class="language-plaintext highlighter-rouge">constant</code> in your
<code class="language-plaintext highlighter-rouge">struts.xml</code> with a path as below:</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.ui.staticContentPath"</span> <span class="na">value=</span><span class="s">"/my-static-content"</span><span class="nt">/&gt;</span>
</code></pre></div></div>
<p>This value is also used by the Default Content Loader.</p>
<h2 id="preventing-struts-from-handling-a-request">Preventing Struts from handling a request</h2>
<p>If there is a request that Struts is handling as an action, and you wish to make Struts ignore it,
you can do so by specifying a comma separated list of regular expressions like:</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.action.excludePattern"</span> <span class="na">value=</span><span class="s">"/some/content/.*,/other/content/.*"</span><span class="nt">/&gt;</span>
</code></pre></div></div>
<p>These regular expression will be evaluated against the request’s URI (<code class="language-plaintext highlighter-rouge">HttpServletRequest.getRequestURI()</code>), and if any
of them matches, then Struts will not handle the request.</p>
<p>To evaluate each pattern the <code class="language-plaintext highlighter-rouge">Pattern</code> class from JDK will be used, you can find more about what kind of pattern you can
use in the <a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/util/regex/Pattern">Pattern class JavaDoc</a>.</p>
<p>Since Struts 6.1.0 you can use a custom separator. By default, the provided patterns are split using comma <code class="language-plaintext highlighter-rouge">,</code>,
but it can happen that you want to use comma in your patterns as well, e.g.: <code class="language-plaintext highlighter-rouge">/static/[a-z]{1,10}.json</code>. In such case
you can define a custom separator to be used to split the patterns, use <code class="language-plaintext highlighter-rouge">struts.action.excludePattern.separator</code>
constant:</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.action.excludePattern.separator"</span> <span class="na">value=</span><span class="s">"//"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;constant</span> <span class="na">name=</span><span class="s">"struts.action.excludePattern"</span> <span class="na">value=</span><span class="s">"/some/[a-zA-Z]{1,10}.json///other/content/.*"</span><span class="nt">/&gt;</span>
</code></pre></div></div>
</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>