struts-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lukaszlen...@apache.org
Subject svn commit: r1009449 [7/10] - in /websites/production/struts/content: ./ bootstrap/css/ fonts/ getting-started/ getting-started/attachments/
Date Fri, 31 Mar 2017 05:44:40 GMT
Added: websites/production/struts/content/getting-started/http-session.html
==============================================================================
--- websites/production/struts/content/getting-started/http-session.html (added)
+++ websites/production/struts/content/getting-started/http-session.html Fri Mar 31 05:44:39 2017
@@ -0,0 +1,348 @@
+<!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>Http Session</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">
+
+  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.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="/downloads.html">Downloads</a></li>
+                <li><a href="/announce.html">Announcements</a></li>
+                <li><a href="http://www.apache.org/licenses/">License</a></li>
+                <li><a href="http://apache.org/foundation/thanks.html">Thanks!</a></li>
+                <li><a href="http://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="/maven/project-info.html">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="/docs/home.html">Getting started</a></li>
+                <li><a href="/docs/tutorials.html">Tutorials</a></li>
+                <li><a href="/docs/faqs.html">FAQs</a></li>
+                <li><a href="/docs/guides.html">Guides</a></li>
+                <li class="divider"></li>
+                <li><a href="/maven/struts2-core/apidocs/index.html">Struts Core API</a></li>
+                <li><a href="/docs/plugins.html">Plugin APIs</a></li>
+                <li><a href="/docs/tag-reference.html">Tag reference</a></li>
+                <li><a href="http://cwiki.apache.org/S2PLUGINS/home.html">Plugin registry</a></li>
+                <li class="divider"></li>
+                <li><a href="/getting-started/getting-started.html">Getting Started (WIP)</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</a></li>
+                <li><a href="/coding-standards.html">Coding standards</a></li>
+                <li class="divider"></li>
+                <li><a href="/releases.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://git-wip-us.apache.org/repos/asf?p=struts.git">Source Repository</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">
+    <h2 id="http-session">HTTP Session</h2>
+
+<p>The example code for this tutorial, http_session, is available at <a href="https://github.com/apache/struts-examples">https://github.com/apache/struts-examples</a></p>
+
+<blockquote>
+
+</blockquote>
+
+<p>#####Introduction#####</p>
+
+<p>Your Struts 2 application may need to access the HTTP session object. Struts 2 provides an interface, <a href="http://struts.apache.org/2.3.1.2/struts2-core/apidocs/org/apache/struts2/interceptor/SessionAware.html">SessionAware</a>^[http://struts.apache.org/2.3.1.2/struts2-core/apidocs/org/apache/struts2/interceptor/SessionAware.html], that your Action class should implement to obtain a reference to the HTTP session object.</p>
+
+<table>
+  <tbody>
+    <tr>
+      <td>The <a href="http://struts.apache.org/mail.html">Struts 2 user mailing list</a>^[http://struts.apache.org/mail.html] 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.</td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <tbody>
+    <tr>
+    </tr>
+  </tbody>
+</table>
+
+<p>#####SessionAware Interface#####</p>
+
+<p>The SessionAware interface has one method, setSession, that your Action class will need to override. In the example application (see above), the HelloWorldAction class implements the SessionAware interface and includes this code:</p>
+
+<p><strong>HelloWorldAction.java setSession Method</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>private Map&lt;String, Object&gt; userSession ;
+
+public void setSession(Map&lt;String, Object) session) {
+
+   userSession = session ;
+
+}
+
+
+</code></pre>
+</div>
+
+<p>The Struts 2 framework has an interceptor that will inject the HTTP session object into the Action class by calling the setSession method.</p>
+
+<p>#####Using the HTTP Session Object In The Action Class#####</p>
+
+<p>The example application keeps track of how many times the user clicks on a Hello link or submits the hello form. It stores this count in the HTTP session object in the increaseHelloCount method.</p>
+
+<p><strong>HelloWorldAction.java increaseHelloCount Method</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>private void increaseHelloCount() {
+			
+   Integer helloCount = (Integer) userSession.get(HELLO_COUNT);
+		
+   if (helloCount == null ) {
+		
+     helloCount = 1;
+			
+   } else {
+			
+     helloCount++;
+
+   }
+		
+   userSession.put(HELLO_COUNT, helloCount);
+	
+}
+
+
+
+</code></pre>
+</div>
+
+<p>When the increaseHelloCount method is called from within the execute method, the userSession object is a reference to the HTTP session object injected by the Struts 2 framework. So any objects stored in the HTTP session can be retrieved using the userSession object and any objects stored in the userSession object will be stored in the HTTP session object.</p>
+
+<p>#####Accessing HTTP Session Objects In The View#####</p>
+
+<p>Struts 2 provides an easy way to get an object stored in the HTTP session from within the view page. In the example application is HelloWorld.jsp with this markup:</p>
+
+<p><strong>HelloWorld.jsp Get helloCount Value From HTTP Session</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>   &lt;p&gt;I've said hello to you &lt;s:property value="#session.helloCount" /&gt; times!&lt;/p&gt;
+
+
+</code></pre>
+</div>
+
+<p>The s:property tag’s value attribute has a value of #session.helloCount. The “#” before the word session tells the Struts framework to look in the session scope for a key of “helloCount” (which is the value of the String constant HELLO_COUNT referenced in method increaseHelloCount). Struts will get the object mapped to helloCount key and then call that object’s toString method to determine what to display in the view page.</p>
+
+<p>#####Best Practices When Using SessionAware#####</p>
+
+<p>Using SessionAware does introduce a potential security vulnerability that you should mitigate by also following these practices in the Action class that implements the SessionAware interface.</p>
+
+<ol>
+  <li>
+    <p>Do not have a public Map&lt;String, Object) getSession method in the Action class. You only need a public void setSession method to implement the SessionAware interface.</p>
+  </li>
+  <li>
+    <p>Also have the Action class implement the <a href="http://struts.apache.org/2.3.1.2/xwork-core/apidocs/com/opensymphony/xwork2/interceptor/ParameterNameAware.html">ParameterNameAware interface</a>^[http://struts.apache.org/2.3.1.2/xwork-core/apidocs/com/opensymphony/xwork2/interceptor/ParameterNameAware.html] and override its acceptableParameterName method:</p>
+  </li>
+</ol>
+
+<p><strong>HelloWorldAction.java acceptableParameterName Method</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>	public boolean acceptableParameterName(String parameterName) {
+		
+		boolean allowedParameterName = true ;
+		
+		if ( parameterName.contains("session")  || parameterName.contains("request") ) {
+		
+			allowedParameterName = false ;
+			
+		} 
+		
+		return allowedParameterName;
+	}
+
+
+</code></pre>
+</div>
+
+<p>This method will be called by the Struts 2 framework for each parameter in the request scope. By returning false if the parameter name contains “session” we are telling the Struts 2 framework to ignore that parameter. This will prevent a malicious user from trying to hack the HTTP session object.</p>
+
+<p>Instead of having each action that implements SessionAware also implement the ParameterNameAware interface you can tell the params interceptor to exclude specific request attributes for all actions in a package. In struts.xml configure the struts-default set of interceptors as follows:</p>
+
+<p><strong>struts.xml configure params interceptor</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>	&lt;package name="basicstruts2" extends="struts-default"&gt;
+
+ 		&lt;interceptors&gt;
+	 		&lt;interceptor-stack name="appDefault"&gt;
+	        	 &lt;interceptor-ref name="defaultStack"&gt;
+	      			&lt;param name="exception.logEnabled"&gt;true&lt;/param&gt;
+	      			&lt;param name="exception.logLevel"&gt;ERROR&lt;/param&gt;
+	      			&lt;param name="params.excludeParams"&gt;dojo..*,^struts..*,^session..*,^request..*,^application..*,^servlet(Request|Response)..*,parameters...*&lt;/param&gt;
+	   			&lt;/interceptor-ref&gt;
+	 	    &lt;/interceptor-stack&gt;
+		&lt;/interceptors&gt;
+		
+		&lt;default-interceptor-ref name="appDefault" /&gt;
+
+
+</code></pre>
+</div>
+
+<p>The above code will ensure that every action in the “basicstruts2” package that implements the SessionAware interface will exclude from processing parameters that starts with the strings provided in the params.excludeParams noded.</p>
+
+<p>The example project includes both methods for mitigating the SessionAware security vulnerability.</p>
+
+<table>
+  <tbody>
+    <tr>
+      <td>Note the same issue exists if you implement the ServletRequestAware interface, which is why the above method returns false if the parameter name contains “request”.</td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <tbody>
+    <tr>
+    </tr>
+  </tbody>
+</table>
+
+<p>#####Summary#####</p>
+
+<p>When your Action class needs to access the HTTP session object implement the SessionAware interface and override the setSession method. Be sure to also implement the ParameterNameAware interface and override the acceptableParameterName method to mitigate a potential security vulnerability. If you have multiple actions that implement SessionAware then consider modifying the params interceptor’s excludeParams value as part of your Struts 2 package setup.</p>
+
+  </section>
+</article>
+
+
+<footer class="container">
+  <div class="col-md-12">
+    Copyright &copy; 2000-2016 <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>
+
+
+<script>
+$(function() {
+  return $("h2, h3, h4, h5, h6").each(function(i, el) {
+    var $el, icon, id;
+    $el = $(el);
+    id = $el.attr('id');
+    icon = '<i class="fa fa-link"></i>';
+    if (id) {
+      return $el.prepend($("<a />").addClass("header-link").attr("href", "#" + id).html(icon));
+    }
+  });
+});
+</script>
+
+</body>
+</html>

Added: websites/production/struts/content/getting-started/introducing-interceptors.html
==============================================================================
--- websites/production/struts/content/getting-started/introducing-interceptors.html (added)
+++ websites/production/struts/content/getting-started/introducing-interceptors.html Fri Mar 31 05:44:39 2017
@@ -0,0 +1,396 @@
+<!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>Introducing Interceptors</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">
+
+  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.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="/downloads.html">Downloads</a></li>
+                <li><a href="/announce.html">Announcements</a></li>
+                <li><a href="http://www.apache.org/licenses/">License</a></li>
+                <li><a href="http://apache.org/foundation/thanks.html">Thanks!</a></li>
+                <li><a href="http://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="/maven/project-info.html">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="/docs/home.html">Getting started</a></li>
+                <li><a href="/docs/tutorials.html">Tutorials</a></li>
+                <li><a href="/docs/faqs.html">FAQs</a></li>
+                <li><a href="/docs/guides.html">Guides</a></li>
+                <li class="divider"></li>
+                <li><a href="/maven/struts2-core/apidocs/index.html">Struts Core API</a></li>
+                <li><a href="/docs/plugins.html">Plugin APIs</a></li>
+                <li><a href="/docs/tag-reference.html">Tag reference</a></li>
+                <li><a href="http://cwiki.apache.org/S2PLUGINS/home.html">Plugin registry</a></li>
+                <li class="divider"></li>
+                <li><a href="/getting-started/getting-started.html">Getting Started (WIP)</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</a></li>
+                <li><a href="/coding-standards.html">Coding standards</a></li>
+                <li class="divider"></li>
+                <li><a href="/releases.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://git-wip-us.apache.org/repos/asf?p=struts.git">Source Repository</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">
+    <h2 id="introducing-interceptors">Introducing Interceptors</h2>
+
+<p>The example code for this tutorial, interceptors, is available at <a href="https://github.com/apache/struts-examples">https://github.com/apache/struts-examples</a></p>
+
+<blockquote>
+
+</blockquote>
+
+<p>#####Introduction#####</p>
+
+<p>So far our tutorials have not delved into the inner workings of the Struts 2 framework. But in this tutorial we’ll introduce a key set of classes the Struts 2 framework relies upon to do most of the work whenever an Action is executed. In this tutorial’s example project there is a register link that is mapped in the Struts XML configuration file (struts.xml) to the execute method of class Register. Before that execute method is called much work is done behind the scenes by the Struts 2 framework. For example:</p>
+
+<ol>
+  <li>
+    <p>Handling any exceptions generated</p>
+  </li>
+  <li>
+    <p>Converting the String request parameters to the Register class’s instance fields where the name values match</p>
+  </li>
+  <li>
+    <p>Calling the validate method and/or the external XML validation</p>
+  </li>
+</ol>
+
+<p>After the execute method is completed more work must be done</p>
+
+<ol>
+  <li>
+    <p>Handling any exceptions generated</p>
+  </li>
+  <li>
+    <p>Converting the Register class’s instance fields to String values for display in the view page</p>
+  </li>
+  <li>
+    <p>Forwarding to the correct view page depending on the result String returned by the execute method</p>
+  </li>
+</ol>
+
+<p>The above list of tasks are not complete - several other tasks are done before and after the execution of the Action.</p>
+
+<table>
+  <tbody>
+    <tr>
+    </tr>
+  </tbody>
+</table>
+
+<p>The benefit of using Struts 2 is all this work happens automatically. You can focus on the logic of the controller (the Struts 2 ActionSupport class), the Service layer, the data access layer, your domain models, etc.</p>
+
+<table>
+  <tbody>
+    <tr>
+      <td>The <a href="http://struts.apache.org/mail.html">Struts 2 user mailing list</a>^[http://struts.apache.org/mail.html] 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.</td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <tbody>
+    <tr>
+    </tr>
+  </tbody>
+</table>
+
+<p>#####Introducing Interceptors#####</p>
+
+<p>The tasks that are done by the Struts 2 framework before and after an Action is executed are done by Struts 2 interceptors. Interceptors are standard Java classes included in the Struts 2 core jar which are executed in a specific order.</p>
+
+<p>In our example application there is a package node in struts.xml. The package node has an attribute of extends with a value of “struts-default.” The value “struts-default” identifies to the framework the specific stack of interceptors that will be executed before and after the Actions in that package.</p>
+
+<p>If you want to learn more about the inner workings of interceptors, what interceptors belong to the struts default stack, and what are all the interceptors included with Struts 2, visit <em>Understanding Interceptors</em> .</p>
+
+<p>Sometime the Struts 2 default stack of interceptors are not exactly what you need for a particular action. You may want to use interceptors that are not part of the Struts 2 default stack. For an individual Action or for the entire package of Actions, you can specify a different stack of interceptors that the Action or package should use. Below is how you would specify that the register Action should use both the <em>logger</em>  and <em>timer</em>  interceptors in addition to the interceptors provided by the default stack.</p>
+
+<p><strong>Specify Specific Interceptors For An Action</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>&lt;action name="register" class="org.apache.struts.register.action.Register" method="execute"&gt;
+	&lt;interceptor-ref name="timer" /&gt;
+	&lt;interceptor-ref name="logger" /&gt;
+	&lt;interceptor-ref name="defaultStack"&gt;
+		&lt;param name="exception.logEnabled"&gt;true&lt;/param&gt;
+		&lt;param name="exception.logLevel"&gt;ERROR&lt;/param&gt;
+	&lt;/interceptor-ref&gt;
+	&lt;result name="success"&gt;thankyou.jsp&lt;/result&gt;
+	&lt;result name="input"&gt;register.jsp&lt;/result&gt;
+&lt;/action&gt;
+
+
+</code></pre>
+</div>
+
+<p>The logger interceptor logs the start and end of the execution of an Action. The timer interceptor logs the amount of time (in milliseconds) for execution of the Action. These two interceptors used together can provide developers useful feedback.</p>
+
+<p>In the code example above note the three interceptor-ref nodes. Each one has a value for the name attribute. For the register Action we are instructing the framework to use the timer, logger, and defaultStack interceptors. The defaultStack are all the interceptors normally executed for an Action.</p>
+
+<p>How did I know to use the value of timer for the name attribute and even that there is a timer interceptor? On the <em>Interceptors</em>  web page in the Struts 2 documentation are a list of interceptors that come with the Struts 2 framework and what the name value is for each interceptor.</p>
+
+<p>How did I know that the timer interceptor isn’t part of the defaultStack of interceptors already? Again on the Interceptors documentation web page is a list of which interceptors belong to the defaultStack.</p>
+
+<p>Note the param nodes. These nodes are used to provide a value to the setLogEnabled and setLogLevel methods of the <em>Exception Interceptor</em> . Providing the values of true and ERROR will cause the Struts 2 framework to log any exceptions not caught by the application’s code and to log those exceptions at the ERROR level.</p>
+
+<p>#####Run The Example#####</p>
+
+<p>In the example application follow the README instructions to build, deploy, and run the application. View the output sent to the JVM console to see the log messages generated by the logger and timer interceptors. You should see log messages similar to the following:</p>
+
+<p>INFO: Starting execution stack for action //register
+ Nov 20, 2010 9:55:48 AM com.opensymphony.xwork2.util.logging.jdk.JdkLogger info</p>
+
+<p>INFO: Finishing execution stack for action //register</p>
+
+<p>Nov 20, 2010 9:55:48 AM com.opensymphony.xwork2.util.logging.jdk.JdkLogger info</p>
+
+<p>INFO: Executed action <a href="https://cwiki.apache.org/register\!execute">//register!execute</a>^[https://cwiki.apache.org/register!execute] took 177 ms.</p>
+
+<p>If you wanted to have the logger and timer interceptors executed for all Actions in a package you would use the following in struts.xml:</p>
+
+<p><strong>Specify Specific Interceptors For A Package</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>&lt;package name="basicstruts2" extends="struts-default" &gt; 
+
+
+       &lt;interceptors&gt; 
+
+         &lt;interceptor-stack name="appDefault"&gt; 
+
+            &lt;interceptor-ref name="timer" /&gt; 
+
+            &lt;interceptor-ref name="logger" /&gt; 
+
+            &lt;interceptor-ref name="defaultStack" /&gt; 
+
+         &lt;/interceptor-stack&gt; 
+
+        &lt;/interceptors&gt;          
+
+        &lt;default-interceptor-ref name="appDefault" /&gt; 
+
+       &lt;!-- rest of package omitted --&gt; 
+
+&lt;/package&gt; 
+
+
+</code></pre>
+</div>
+
+<p>In the code above we use the interceptors node to define a new stack of interceptors that includes the timer, logger, and defaultStack interceptors. We give this new interceptor stack a name of appDefault. Then we use the default-interceptor-ref node to specify that for all Actions defined inside this package node the appDefault stack of interceptors are to be used. Thus the timer and logger interceptor will be executed for each Action in this package.</p>
+
+<p>Note that in both examples we are still executing all the other interceptors by including the defaultStack as one of the interceptor-ref nodes. When you specify what interceptors you want to use for an Action or a package then only those interceptors are executed. So if in the example we had left out the interceptor-ref for defaultStack only the logger and timer interceptors would have executed.</p>
+
+<p>#####Create Your Own Interceptor#####</p>
+
+<p>In addition to specifying your own stack of interceptors, you can also write your own new interceptor and add it to the stack that is executed. The Struts <em>Writing Interceptors</em>  guide explains how to do this. For example, you could create your own interceptor to handle authentication and authorization.</p>
+
+<p>#####Summary#####</p>
+
+<p>Interceptors provide the Struts 2 framework with both power and flexibility. Developers may add additional interceptors (either ones provided by Struts 2 or ones they create) to the stack of interceptors executed when an Action class is called.</p>
+
+<p>For more information about interceptors consult the Struts 2 <em>Interceptor</em>  documentation.</p>
+
+<p>##Preparable Interface## {#PAGE_27839279}</p>
+
+<p>The example code for this tutorial, preparable_interface, is available at <a href="https://github.com/apache/struts-examples">https://github.com/apache/struts-examples</a>.</p>
+
+<blockquote>
+
+</blockquote>
+
+<p>#####Introduction#####</p>
+
+<p>Often the data used to populate a form control is dynamically generated, perhaps from a database. When the user submits the form, the Struts 2 validation interceptor attempts to validate the user’s form input. If validation fails the Struts 2 framework returns the value “input” but the “input” action is not re-executed. Rather the view associated with the “input” result is rendered to the user. Usually this view is the page that displayed the original form.</p>
+
+<p>This work-flow can cause a problem if one or more of the form fields or some other data displayed depends on a dynamic look-up that that is accomplished in the Action class’s input method. Since the Action class’s input method is not re-executed when validation fails, the view page may no longer have access to the correct information to create the form or other display information.</p>
+
+<table>
+  <tbody>
+    <tr>
+      <td>The <a href="http://struts.apache.org/mail.html">Struts 2 user mailing list</a>^[http://struts.apache.org/mail.html] 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.</td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <tbody>
+    <tr>
+    </tr>
+  </tbody>
+</table>
+
+<p>#####Preparable Interface#####</p>
+
+<p>Struts 2 provides the <a href="http://struts.apache.org/2.3.1/xwork-core/apidocs/com/opensymphony/xwork2/Preparable.html">Preparable interface</a>^[http://struts.apache.org/2.3.1/xwork-core/apidocs/com/opensymphony/xwork2/Preparable.html] to overcome this problem. An Action class that implements this interface must override the prepare method. The prepare method will always be called by the Struts 2 framework’s <a href="http://struts.apache.org/2.3.1.2/docs/prepare-interceptor.html">prepare interceptor</a>^[http://struts.apache.org/2.3.1.2/docs/prepare-interceptor.html] whenever any method is called for the Action class and also when validation fails before the view is rendered.</p>
+
+<p>In the prepare method you should put any statements that must be executed no matter what other Action class method will be called and also statements that should be executed if validation fails. Usually statements in the prepare method set the value for Action class instance fields that will be used to populate form controls and get the values that will be used to set the initial form field values.</p>
+
+<p>In addition to automatically running the prepare method the <a href="http://struts.apache.org/2.3.1.2/docs/prepare-interceptor.html">prepare interceptor</a>^[http://struts.apache.org/2.3.1.2/docs/prepare-interceptor.html] will also call a method named prepare[ActionMethodName]. For example, define a prepare method and a prepareInput method in the Action class that implements preparable. When the Struts 2 framework calls the input method, the prepare interceptor will call the prepareInput and the prepare methods before calling the input method.</p>
+
+<p>#####Example Application#####</p>
+
+<p>If you examine class EditAction in the example application (see above) you’ll see that it implements the Preparable Interface. In the prepare method is this code:</p>
+
+<p><strong>EditAction.java prepare Method</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>		
+   carModelsAvailable = carModelsService.getCarModels() ;
+		
+   setPersonBean( editService.getPerson() );
+
+
+</code></pre>
+</div>
+
+<p>The above statements get the car model values used to populate the car model check boxes displayed in the form and also get the information about the Person object being edited.</p>
+
+<p>When you run the example application, look in the log to see when the prepare method is called in relation to the input and execute methods. Running the example application and examining the log should help you understand the impact of implementing the Preparable Interface and the prepare method.</p>
+
+<p>#####Summary#####</p>
+
+<p>When your application requires specific statements to be executed no matter which method of the Action class is called or when validation fails, you should implement the Preparable interface and override the prepare method.</p>
+
+  </section>
+</article>
+
+
+<footer class="container">
+  <div class="col-md-12">
+    Copyright &copy; 2000-2016 <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>
+
+
+<script>
+$(function() {
+  return $("h2, h3, h4, h5, h6").each(function(i, el) {
+    var $el, icon, id;
+    $el = $(el);
+    id = $el.attr('id');
+    icon = '<i class="fa fa-link"></i>';
+    if (id) {
+      return $el.prepend($("<a />").addClass("header-link").attr("href", "#" + id).html(icon));
+    }
+  });
+});
+</script>
+
+</body>
+</html>

Added: websites/production/struts/content/getting-started/message-resource-files.html
==============================================================================
--- websites/production/struts/content/getting-started/message-resource-files.html (added)
+++ websites/production/struts/content/getting-started/message-resource-files.html Fri Mar 31 05:44:39 2017
@@ -0,0 +1,450 @@
+<!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>Message Resource Files</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">
+
+  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.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="/downloads.html">Downloads</a></li>
+                <li><a href="/announce.html">Announcements</a></li>
+                <li><a href="http://www.apache.org/licenses/">License</a></li>
+                <li><a href="http://apache.org/foundation/thanks.html">Thanks!</a></li>
+                <li><a href="http://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="/maven/project-info.html">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="/docs/home.html">Getting started</a></li>
+                <li><a href="/docs/tutorials.html">Tutorials</a></li>
+                <li><a href="/docs/faqs.html">FAQs</a></li>
+                <li><a href="/docs/guides.html">Guides</a></li>
+                <li class="divider"></li>
+                <li><a href="/maven/struts2-core/apidocs/index.html">Struts Core API</a></li>
+                <li><a href="/docs/plugins.html">Plugin APIs</a></li>
+                <li><a href="/docs/tag-reference.html">Tag reference</a></li>
+                <li><a href="http://cwiki.apache.org/S2PLUGINS/home.html">Plugin registry</a></li>
+                <li class="divider"></li>
+                <li><a href="/getting-started/getting-started.html">Getting Started (WIP)</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</a></li>
+                <li><a href="/coding-standards.html">Coding standards</a></li>
+                <li class="divider"></li>
+                <li><a href="/releases.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://git-wip-us.apache.org/repos/asf?p=struts.git">Source Repository</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">
+    <h2 id="message-resource-files">Message Resource Files</h2>
+
+<p>This tutorial assumes you’ve completed the <em>Form Validation</em>  tutorial and have a working form_validation project. The example code for this tutorial, message_resource, is available for checkout from the</p>
+
+<blockquote>
+  <p>Struts 2 GitHub repository at <a href="https://github.com/apache/struts-examples">https://github.com/apache/struts-examples</a>.</p>
+</blockquote>
+
+<blockquote>
+
+</blockquote>
+
+<p><strong>Introduction</strong></p>
+
+<p>In this tutorial we’ll explore using Struts 2 message resource capabilities (also called resource bundles). Message resources provide a simple way to put text in a view page that is the same through out your application, to create form field labels, and to change text to a specific language based on the user’s locale (i18n).</p>
+
+<table>
+  <tbody>
+    <tr>
+      <td>The <a href="http://struts.apache.org/mail.html">Struts 2 user mailing list</a>^[http://struts.apache.org/mail.html] 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.</td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <tbody>
+    <tr>
+    </tr>
+  </tbody>
+</table>
+
+<p><strong>Message Resource Property Files</strong></p>
+
+<p>In a Struts 2 web application you may associate a message resource property file with each Struts 2 Action class by creating a properties file with the same name as the Action class and having the .properties extension. This properties file must go in the same package as the Action class. For our tutorial example, let’s say we want to place the form field labels into a separate file where we can easily change them and also provide the capability to display the labels in other languages.</p>
+
+<p>If you’re doing this tutorial after completing <em>Form Validation</em>  then you can make these changes to that tutorial’s example application.</p>
+
+<p>Put the text below in a file named Register.properties in the org.apache.struts.register.action package in the src/resources/java folder.</p>
+
+<p><strong>Register.properties</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>personBean.firstName=First name
+personBean.lastName=Last name
+personBean.age=Age
+personBean.email=Email
+thankyou=Thank you for registering %{personBean.firstName}.
+
+</code></pre>
+</div>
+
+<p>The above is just a standard Java properties file. The key is to the left of the = sign and the value for the key is to the right. When the Register action is executed these properties will be available to the view page by referencing the key name.</p>
+
+<p><strong>Struts 2 Key Attribute</strong></p>
+
+<p>The Struts 2 key attribute can be used in the <em>textfield</em>  tag to instruct the framework what value to use for the textfield’s name and label attributes. Instead of providing those attributes and their values directly, you can just use the key attribute.</p>
+
+<p>If you open register.jsp from the <em>Form Validation</em>  tutorial you’ll see this Struts 2 textfield tag:</p>
+
+<p><strong>textfield tag</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>&lt;s:textfield name="personBean.firstName" label="First name" /&gt;
+
+</code></pre>
+</div>
+
+<p>Instead of specifying the name and label attributes you can just use the key attribute.</p>
+
+<p><strong>textfield tag with key attribute</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>&lt;s:textfield key="personBean.firstName"  /&gt;
+
+</code></pre>
+</div>
+
+<p>The value for the key attribute instructs the Struts 2 framework to use the same value for the name attribute (personBean.firstName). For the label attribute’s value the value of the key attribute is used by the Struts 2 framework to find a key in a properties file with the same value. So in our example, Struts 2 will look in Register.properties for a key with a value of personBean.firstName. The value of that key (First name) will be used as the label attribute’s value.</p>
+
+<p>To enable the key attribute to find the properties file, the display of the view page must be the result of executing a Struts 2 Action class. Right now if you examine index.jsp from the <em>Form Validation</em>  tutorial the link to the register.jsp page is a standard URL.</p>
+
+<p><strong>link to register.jsp</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>&lt;p&gt;&lt;a href="register.jsp"&gt;Please register&lt;/a&gt; for our prize drawing.&lt;/p&gt;
+
+</code></pre>
+</div>
+
+<p>We need to change the above link so that it goes through the Register.java Struts 2 Action class. Replace the above with this markup.</p>
+
+<p><strong>link to Register Action class</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>&lt;s:url action="registerInput" var="registerInputLink" /&gt;
+&lt;p&gt;&lt;a href="${registerInputLink}"&gt;Please register&lt;/a&gt; for our prize drawing.&lt;/p&gt;
+
+</code></pre>
+</div>
+
+<p>We use the Struts 2 url tag to create a link to action registerInput. We then use that link as the value for the href attribute of the anchor tag. We must define the registerInput action in struts.xml. Add the following to struts.xml.</p>
+
+<p><strong>registerInput action node for struts.xml</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>&lt;action name="registerInput" class="org.apache.struts.register.action.Register" method="input" &gt;
+	&lt;result name="input"&gt;/register.jsp&lt;/result&gt;
+&lt;/action&gt;
+
+</code></pre>
+</div>
+
+<p>The above action node instructs the Struts 2 framework to execute class Register’s input method in response to action registerInput. The input method is inherited by class Register from class ActionSupport. The default behavior of the inherited input method is to return the String input. The result node above specifies that if the returned result is “input” then render the view register.jsp.</p>
+
+<p>By doing the above the view page register.jsp will have access to the properties defined in Register.properties. The Struts 2 framework will make those properties defined in Register.properties available to the view page since the view page was rendered after Register.java (the Struts 2 Action class) was executed.</p>
+
+<p>Follow the instructions (README.txt) in the project to create the war file and copy the war file to your servlet container. Open a web browser and navigate to the home page specified in the README.txt file (index.action). You should see a link to registerInput.action when mousing over the hyperlink Please Register.</p>
+
+<p><img src="attachments/att14975007_registerInput.png" alt="registerInput.png" /></p>
+
+<p>When you click on the Please Register link your browser should display the register.jsp. The form field labels should be the key values from the Register.properties file.</p>
+
+<p><img src="attachments/att14975006_register.png" alt="register.png" /></p>
+
+<p><strong>Struts 2 Text Tag</strong></p>
+
+<p>We can also use the Struts 2 text tag to display values from a properties file. In thankyou.jsp add this text tag instead of the h3 tag that is in thankyou.jsp.</p>
+
+<p><strong>text tag</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>&lt;h3&gt;&lt;s:text name="thankyou" /&gt;&lt;/h3&gt;
+
+</code></pre>
+</div>
+
+<p>Since thankyou.jsp is also rendered after executing the Register.java Action class, the key thankyou and its value will be available to the view page.</p>
+
+<p><img src="attachments/att14975009_thankyou.png" alt="thankyou.png" /></p>
+
+<p>How did the value entered for the first name input field get displayed on thankyou.jsp? Look back at the value for the thankyou key in the Register.properties file.</p>
+
+<p><strong>Register.properties</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>thankyou=Thank you for registering %{personBean.firstName}.
+
+</code></pre>
+</div>
+
+<p>The markup %{personBean.firstName} tells Struts 2 to replace this part with the result of calling getPersonBean, which returns a Person object. Then call the getFirstName method which returns a String (the value the user inputted into the personBean.firstName form field on register.jsp).</p>
+
+<p><strong>Package Level Properties</strong></p>
+
+<p>What if you want a properties file with keys and values that can be referenced from multiple view pages and those view pages are rendered after executing different Action classes? Struts 2 has the ability to use multiple property files provided the property file is found in the package hierarchy.</p>
+
+<p>Place the following in a file named package.properties and save that file in package org.apache.struts in src/main/resources.</p>
+
+<p><strong>package.properties</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>greeting=Welcome to The Wonderful World of Struts 2
+
+</code></pre>
+</div>
+
+<p>Now any view rendered by an Action that is in the hierarchy org.apache.struts… can use a Struts 2 text tag with a name attribute value of “greeting” to display the value of the greeting property key. For example add the following markup to helloworld.jsp before the h2 tag.</p>
+
+<p><strong>Using properties set in package.properties</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>&lt;h1&gt;&lt;s:text name="greeting" /&gt;&lt;/h1&gt;
+
+</code></pre>
+</div>
+
+<p>Then rebuild the war file and deploy it to your servlet container. Go to index.action and click on the link for Hello World. You should see:</p>
+
+<p><img src="attachments/att14975005_hellogreeting.png" alt="hellogreeting.png" /></p>
+
+<p>The property keys and values defined in package.properties are available to any view that is rendered after executing an Action class that is the package hierarchy that includes package.properties.</p>
+
+<p><strong>Global Properties</strong></p>
+
+<p>You can also specify a global property file in struts.xml. The keys and values defined in that property file will be available to all the view pages that are rendered after executing an Action class.</p>
+
+<p>Add the following to a file named global.properties (note the name doesn’t have to be global).</p>
+
+<p><strong>global.properties</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>contact=For assistance contact &lt;a href='mailto:contact@email.com'&gt;contact@email.com&lt;/a&gt;
+
+</code></pre>
+</div>
+
+<p>Save the global.properties file in the src/main/resources folder.</p>
+
+<p>To inform the Struts 2 framework about the global.properties file add the follow node to struts.xml after the constant name=”struts.devmode” node.</p>
+
+<p><strong>Specify Global Property File In struts.xml</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>&lt;constant name="struts.custom.i18n.resources" value="global" /&gt;
+
+</code></pre>
+</div>
+
+<p>To use the contact key in a view page, add the following markup to index.jsp just before the closing body tag.</p>
+
+<p><strong>Using contact property</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>&lt;hr /&gt;
+&lt;s:text name="contact" /&gt;
+
+</code></pre>
+</div>
+
+<p>Rebuild the war file, deploy it to your Servlet container, and then go to index.action. You should see:</p>
+
+<p><img src="attachments/att14975004_contact.png" alt="contact.png" /></p>
+
+<p>Struts 2 will look for a property key of contact in all the property files starting with the property file that matches the Action class, then in the property files that are in the package hierarchy of the Action class, and then in any property files specified in struts.xml. For this example Struts 2 will find the contact key in global.properties. The value of the contact key will be displayed where we have put the text tag.</p>
+
+<p>You can add the text tag above to all the JSPs in this example.</p>
+
+<p><strong>Internationalization (i18n)</strong></p>
+
+<p>Using message resource files (resource bundles) also enables you to provide text in different languages. By default, Struts 2 will use the user’s default locale. If that locale is en for English then the property files used will be the ones without a locale specification (for example Register.properties). If the locale is not English but say Spanish (es) then Struts 2 will look for a properties file named Register_es.properties.</p>
+
+<p>To provide an example of Struts 2 support for i18n create a file named Register_es.properties and in that file add the following Spanish translations.</p>
+
+<p><strong>Register_es.properties</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>personBean.firstName=Nombre
+personBean.lastName=Apellidos
+personBean.age=Edad
+personBean.email=Correo
+thankyou=Gracias por registrarse, %{personBean.firstName}. 
+
+</code></pre>
+</div>
+
+<table>
+  <tbody>
+    <tr>
+      <td>My apologies to Spanish language speakers for any mistakes in the Spanish translations.</td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <tbody>
+    <tr>
+    </tr>
+  </tbody>
+</table>
+
+<p>Save the Register_es.properties file in the same package as Register.properties.</p>
+
+<p>In our example application, we need to tell Struts 2 to use a locale value of es (since we’re not in a Spanish locale) instead of the default locale value of our location (which is en). Add the following markup to index.jsp.</p>
+
+<p><strong>Specify The Locale As a URL Parameter</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>&lt;h3&gt;Registro español&lt;/h3&gt;
+&lt;s:url action="registerInput" var="registerInputLinkES"&gt;
+    &lt;s:param name="request_locale"&gt;es&lt;/s:param&gt;
+&lt;/s:url&gt;
+&lt;p&gt;&lt;a href="${registerInputLinkES}"&gt;Por favor, regístrese&lt;/a&gt; para nuestro sorteo&lt;/p&gt;
+
+</code></pre>
+</div>
+
+<p>In the above markup we’ve added a parameter named request_locale to the URL. The value of that parameter is es. The Action class that responds to this URL (Register.java) will see that the locale is es and will look for property files with _es (for example Register_es.properties). It will use those property files to find the values of the property keys referenced by the view page (e.g. personBean.firstName).</p>
+
+<p>After clicking on the above link you should see the same form as before but with the form field labels in Spanish.</p>
+
+<p><img src="attachments/att14975008_spanishform.png" alt="spanishform.png" /></p>
+
+<p>If we implement the same concept by creating _es.properties versions of global.properties (global_es.properties) and package.properties (package_es.properties) then we can create a complete registration web page in Spanish. Download the finished example application for this tutorial from Google Code - <a href="http://code.google.com/p/struts2-examples/downloads/list">http://code.google.com/p/struts2-examples/downloads/list</a> to see those property files and run the complete example with the registration form in Spanish.</p>
+
+<p><strong>Summary</strong></p>
+
+<p>We’ve covered how to use message resources (resource bundles) in Struts 2 and also introduced how Struts 2 enables internationalization (i18n) in this tutorial. To fully understand these concepts and learn more about Struts 2 consult the main Struts 2 documentation available at <a href="http://struts.apache.org">http://struts.apache.org</a>.</p>
+
+  </section>
+</article>
+
+
+<footer class="container">
+  <div class="col-md-12">
+    Copyright &copy; 2000-2016 <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>
+
+
+<script>
+$(function() {
+  return $("h2, h3, h4, h5, h6").each(function(i, el) {
+    var $el, icon, id;
+    $el = $(el);
+    id = $el.attr('id');
+    icon = '<i class="fa fa-link"></i>';
+    if (id) {
+      return $el.prepend($("<a />").addClass("header-link").attr("href", "#" + id).html(icon));
+    }
+  });
+});
+</script>
+
+</body>
+</html>

Added: websites/production/struts/content/getting-started/preperable-interface.html
==============================================================================
--- websites/production/struts/content/getting-started/preperable-interface.html (added)
+++ websites/production/struts/content/getting-started/preperable-interface.html Fri Mar 31 05:44:39 2017
@@ -0,0 +1,237 @@
+<!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>Preperable Interface</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">
+
+  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.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="/downloads.html">Downloads</a></li>
+                <li><a href="/announce.html">Announcements</a></li>
+                <li><a href="http://www.apache.org/licenses/">License</a></li>
+                <li><a href="http://apache.org/foundation/thanks.html">Thanks!</a></li>
+                <li><a href="http://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="/maven/project-info.html">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="/docs/home.html">Getting started</a></li>
+                <li><a href="/docs/tutorials.html">Tutorials</a></li>
+                <li><a href="/docs/faqs.html">FAQs</a></li>
+                <li><a href="/docs/guides.html">Guides</a></li>
+                <li class="divider"></li>
+                <li><a href="/maven/struts2-core/apidocs/index.html">Struts Core API</a></li>
+                <li><a href="/docs/plugins.html">Plugin APIs</a></li>
+                <li><a href="/docs/tag-reference.html">Tag reference</a></li>
+                <li><a href="http://cwiki.apache.org/S2PLUGINS/home.html">Plugin registry</a></li>
+                <li class="divider"></li>
+                <li><a href="/getting-started/getting-started.html">Getting Started (WIP)</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</a></li>
+                <li><a href="/coding-standards.html">Coding standards</a></li>
+                <li class="divider"></li>
+                <li><a href="/releases.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://git-wip-us.apache.org/repos/asf?p=struts.git">Source Repository</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">
+    <h2 id="preparable-interface">Preparable Interface</h2>
+
+<p>The example code for this tutorial, preparable_interface, is available at <a href="https://github.com/apache/struts-examples">https://github.com/apache/struts-examples</a>.</p>
+
+<blockquote>
+
+</blockquote>
+
+<p>#####Introduction#####</p>
+
+<p>Often the data used to populate a form control is dynamically generated, perhaps from a database. When the user submits the form, the Struts 2 validation interceptor attempts to validate the user’s form input. If validation fails the Struts 2 framework returns the value “input” but the “input” action is not re-executed. Rather the view associated with the “input” result is rendered to the user. Usually this view is the page that displayed the original form.</p>
+
+<p>This work-flow can cause a problem if one or more of the form fields or some other data displayed depends on a dynamic look-up that that is accomplished in the Action class’s input method. Since the Action class’s input method is not re-executed when validation fails, the view page may no longer have access to the correct information to create the form or other display information.</p>
+
+<table>
+  <tbody>
+    <tr>
+      <td>The <a href="http://struts.apache.org/mail.html">Struts 2 user mailing list</a>^[http://struts.apache.org/mail.html] 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.</td>
+    </tr>
+  </tbody>
+</table>
+
+<table>
+  <tbody>
+    <tr>
+    </tr>
+  </tbody>
+</table>
+
+<p>#####Preparable Interface#####</p>
+
+<p>Struts 2 provides the <a href="http://struts.apache.org/2.3.1/xwork-core/apidocs/com/opensymphony/xwork2/Preparable.html">Preparable interface</a>^[http://struts.apache.org/2.3.1/xwork-core/apidocs/com/opensymphony/xwork2/Preparable.html] to overcome this problem. An Action class that implements this interface must override the prepare method. The prepare method will always be called by the Struts 2 framework’s <a href="http://struts.apache.org/2.3.1.2/docs/prepare-interceptor.html">prepare interceptor</a>^[http://struts.apache.org/2.3.1.2/docs/prepare-interceptor.html] whenever any method is called for the Action class and also when validation fails before the view is rendered.</p>
+
+<p>In the prepare method you should put any statements that must be executed no matter what other Action class method will be called and also statements that should be executed if validation fails. Usually statements in the prepare method set the value for Action class instance fields that will be used to populate form controls and get the values that will be used to set the initial form field values.</p>
+
+<p>In addition to automatically running the prepare method the <a href="http://struts.apache.org/2.3.1.2/docs/prepare-interceptor.html">prepare interceptor</a>^[http://struts.apache.org/2.3.1.2/docs/prepare-interceptor.html] will also call a method named prepare[ActionMethodName]. For example, define a prepare method and a prepareInput method in the Action class that implements preparable. When the Struts 2 framework calls the input method, the prepare interceptor will call the prepareInput and the prepare methods before calling the input method.</p>
+
+<p>#####Example Application#####</p>
+
+<p>If you examine class EditAction in the example application (see above) you’ll see that it implements the Preparable Interface. In the prepare method is this code:</p>
+
+<p><strong>EditAction.java prepare Method</strong></p>
+
+<div class="highlighter-rouge"><pre class="highlight"><code>		
+   carModelsAvailable = carModelsService.getCarModels() ;
+		
+   setPersonBean( editService.getPerson() );
+
+
+</code></pre>
+</div>
+
+<p>The above statements get the car model values used to populate the car model check boxes displayed in the form and also get the information about the Person object being edited.</p>
+
+<p>When you run the example application, look in the log to see when the prepare method is called in relation to the input and execute methods. Running the example application and examining the log should help you understand the impact of implementing the Preparable Interface and the prepare method.</p>
+
+<p>#####Summary#####</p>
+
+<p>When your application requires specific statements to be executed no matter which method of the Action class is called or when validation fails, you should implement the Preparable interface and override the prepare method.</p>
+
+  </section>
+</article>
+
+
+<footer class="container">
+  <div class="col-md-12">
+    Copyright &copy; 2000-2016 <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>
+
+
+<script>
+$(function() {
+  return $("h2, h3, h4, h5, h6").each(function(i, el) {
+    var $el, icon, id;
+    $el = $(el);
+    id = $el.attr('id');
+    icon = '<i class="fa fa-link"></i>';
+    if (id) {
+      return $el.prepend($("<a />").addClass("header-link").attr("href", "#" + id).html(icon));
+    }
+  });
+});
+</script>
+
+</body>
+</html>



Mime
View raw message