You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by ad...@apache.org on 2015/02/03 12:19:21 UTC

svn commit: r1656683 [6/7] - in /wicket/common/site/trunk/_site: ./ 2015/ 2015/02/ 2015/02/02/ guide/ guide/gapi/ guide/gapi/DefaultPackage/ guide/gapi/spring/ guide/guide/ guide/guide/pages/

Modified: wicket/common/site/trunk/_site/guide/guide/single.html
URL: http://svn.apache.org/viewvc/wicket/common/site/trunk/_site/guide/guide/single.html?rev=1656683&r1=1656682&r2=1656683&view=diff
==============================================================================
--- wicket/common/site/trunk/_site/guide/guide/single.html (original)
+++ wicket/common/site/trunk/_site/guide/guide/single.html Tue Feb  3 11:19:18 2015
@@ -408,9 +408,11 @@ function addJsClass(el) {
                             
                             <div class="toc-item" style="margin-left:10px"><a href="#security_3"><strong>21.3</strong><span>Using HTTPS protocol</span></a></div>
                             
-                            <div class="toc-item" style="margin-left:10px"><a href="#security_4"><strong>21.4</strong><span>Package Resource Guard</span></a></div>
+                            <div class="toc-item" style="margin-left:10px"><a href="#security_4"><strong>21.4</strong><span>URLs encryption in detail</span></a></div>
                             
-                            <div class="toc-item" style="margin-left:10px"><a href="#security_5"><strong>21.5</strong><span>Summary</span></a></div>
+                            <div class="toc-item" style="margin-left:10px"><a href="#security_5"><strong>21.5</strong><span>Package Resource Guard</span></a></div>
+                            
+                            <div class="toc-item" style="margin-left:10px"><a href="#security_6"><strong>21.6</strong><span>Summary</span></a></div>
                             
                             <div class="toc-item" style="margin-left:0px"><a href="#testing"><strong>22</strong><span>Test Driven Development with Wicket</span></a></div>
                             
@@ -490,6 +492,8 @@ function addJsClass(el) {
                             
                             <div class="toc-item" style="margin-left:10px"><a href="#wicketstuff_6"><strong>27.6</strong><span>Module wicketstuff-rest-annotations</span></a></div>
                             
+                            <div class="toc-item" style="margin-left:10px"><a href="#wicketstuff_7"><strong>27.7</strong><span>Module stateless</span></a></div>
+                            
                             <div class="toc-item" style="margin-left:0px"><a href="#redirects"><strong>28</strong><span>Lost In Redirection With Apache Wicket (Appendix)</span></a></div>
                             
                             <div class="toc-item" style="margin-left:0px"><a href="#contributing"><strong>29</strong><span>Contributing to this guide (Appendix)</span></a></div>
@@ -1174,12 +1178,12 @@ For more details about page storing you
 </blockquote><p class="paragraph"/>As we have stated at the beginning of this chapter, page versions are stored using Java serialization, therefore every object referenced inside a page must be serializable. In paragraph 9.6 we will see how to overcome this limit and work with non-serializable objects in our components using detachable Wicket models.<p class="paragraph"/><h3>Using a specific page version with PageReference</h3><p class="paragraph"/>To retrieve a specific page version in our code we can use class <code>org.apache.wicket.PageReference</code> by providing its constructor with the corresponding page id:<p class="paragraph"/><div class="code"><pre>//load page version with page id = 3
 PageReference pageReference = <span class="java&#45;keyword">new</span> PageReference(3);
 //load the related page instance
-Page page = pageReference.getPage();</pre></div><p class="paragraph"/>To get the related page instance we must use method getPage.<p class="paragraph"/><h3>Turning off page versioning</h3><p class="paragraph"/>If for any reason we need to switch off versioning for a given page, we can call its method setVersioned(false).<p class="paragraph"/><h3>Pluggable serialization</h3><p class="paragraph"/>Starting from version 1.5 it is possible to choose which implementation of Java serialization will be used by Wicket to store page versions. Wicket serializes pages using an implementation of interface <code>org.apache.wicket.serialize.ISerializer</code>. The default implementation is <code>org.apache.wicket.serialize.java.JavaSerializer</code> and it uses the standard Java serialization mechanism based on classes ObjectOutputStream and ObjectInputStream. However on Internet we can find other interesting serialization libraries like Kryo1 which performs faster then the standard implementation
 .The serializer in use can be customized with the setSerializer(ISerializer) method defined by setting interface <code>org.apache.wicket.settings.IFrameworkSettings</code>.<p class="paragraph"/>We can access this interface inside the method init of the class Application using the getFrameworkSettings() method :<p class="paragraph"/><div class="code"><pre>@Override
+Page page = pageReference.getPage();</pre></div><p class="paragraph"/>To get the related page instance we must use method getPage.<p class="paragraph"/><h3>Turning off page versioning</h3><p class="paragraph"/>If for any reason we need to switch off versioning for a given page, we can call its method setVersioned(false).<p class="paragraph"/><h3>Pluggable serialization</h3><p class="paragraph"/>Starting from version 1.5 it is possible to choose which implementation of Java serialization will be used by Wicket to store page versions. Wicket serializes pages using an implementation of interface <code>org.apache.wicket.serialize.ISerializer</code>. The default implementation is <code>org.apache.wicket.serialize.java.JavaSerializer</code> and it uses the standard Java serialization mechanism based on classes ObjectOutputStream and ObjectInputStream. However on Internet we can find other interesting serialization libraries like <a href="https://github.com/EsotericSoftware/kryo" target="b
 lank">Kryo</a> or <a href="http://ruedigermoeller.github.io/fast-serialization/" target="blank">Fast</a> which perform faster then the standard implementation. The serializer in use can be customized with the setSerializer(ISerializer) method defined by setting interface <code>org.apache.wicket.settings.IFrameworkSettings</code>.<p class="paragraph"/>We can access this interface inside the method init of the class Application using the getFrameworkSettings() method :<p class="paragraph"/><div class="code"><pre>@Override
 <span class="java&#45;keyword">public</span> void init()
 &#123;
 	<span class="java&#45;keyword">super</span>.init();
 	getFrameworkSettings().setSerializer(yourSerializer);
-&#125;</pre></div><p class="paragraph"/>A serializer based on Kryo library is provided by the WicketStuff project. You can find more information on this project, as well as the instructions to use its modules, in Appendix B.<p class="paragraph"/><h3>Page caching</h3><p class="paragraph"/>By default Wicket persists versions of pages into a session-relative file on disk, but it uses a two-levels cache to speed up this process. The first level of the cache uses a http session attribute called “wicket:persistentPageManagerData-&#60;APPLICATION_NAME&#62;” to store pages. The second level cache stores pages into application-scoped variables which are identified by a session id and a page id.<p class="paragraph"/>The following picture is an overview of these two caching levels:<p class="paragraph"/><img border="0" class="center" src="../img/wicket-cache.png"></img><p class="paragraph"/>The session-scoped cache is faster then the other memory levels but it contains only the pages 
 used to serve the last request. Wicket allows us to set the maximum amount of memory allowed for the application-scoped cache and for the page store file. Both parameters can be configured via setting interface <code>org.apache.wicket.settings.IStoreSettings</code>.<p class="paragraph"/>This interface provides the setMaxSizePerSession(Bytes bytes) method to set the size for page store file. The Bytes parameter is the maximum size allowed for this file:<p class="paragraph"/><div class="code"><pre>@Override
+&#125;</pre></div><p class="paragraph"/>A serializer based on Kryo library and another one based on Fast are provided by the WicketStuff project. You can find more information on this project, as well as the instructions to use its modules, in Appendix B.<p class="paragraph"/><h3>Page caching</h3><p class="paragraph"/>By default Wicket persists versions of pages into a session-relative file on disk, but it uses a two-levels cache to speed up this process. The first level of the cache uses a http session attribute called “wicket:persistentPageManagerData-&#60;APPLICATION_NAME&#62;” to store pages. The second level cache stores pages into application-scoped variables which are identified by a session id and a page id.<p class="paragraph"/>The following picture is an overview of these two caching levels:<p class="paragraph"/><img border="0" class="center" src="../img/wicket-cache.png"></img><p class="paragraph"/>The session-scoped cache is faster then the other memory levels 
 but it contains only the pages used to serve the last request. Wicket allows us to set the maximum amount of memory allowed for the application-scoped cache and for the page store file. Both parameters can be configured via setting interface <code>org.apache.wicket.settings.IStoreSettings</code>.<p class="paragraph"/>This interface provides the setMaxSizePerSession(Bytes bytes) method to set the size for page store file. The Bytes parameter is the maximum size allowed for this file:<p class="paragraph"/><div class="code"><pre>@Override
 <span class="java&#45;keyword">public</span> void init()
 &#123;
 	<span class="java&#45;keyword">super</span>.init();
@@ -1494,12 +1498,15 @@ setResponsePage(MountedPageWithPlacehold
 		pageParameters.add(<span class="java&#45;quote">"foo"</span>, <span class="java&#45;quote">"foo"</span>);
 		pageParameters.add(<span class="java&#45;quote">"bar"</span>, <span class="java&#45;quote">"bar"</span>);<p class="paragraph"/>		setResponsePage(MountedPage.class, pageParameters);
 	&#125;
-&#125;);</pre></div><p class="paragraph"/>Generated URL:<p class="paragraph"/><div class="code"><pre>&#60;Application path&#62;/mountedPath/foo/foo/bar/bar?1</pre></div><p class="paragraph"/><h3>Encrypting page URLs</h3><p class="paragraph"/>Sometimes URLs are a double–edged sword for our site because they can expose too many details about the internal structure of our web application and malicious users could exploit them to perform a <a href="http://en.wikipedia.org/wiki/Cross-site_request_forgery" target="blank">cross-site request forgery</a> .<p class="paragraph"/>To avoid this kind of security threat we can use the CryptoMapper request mapper which wraps an existing mapper and encrypts the original URL producing a single encrypted segment:<p class="paragraph"/><img border="0" class="center" src="../img/url-encrypted.png"></img><p class="paragraph"/>Typically, CryptoMapper is registered into a Wicket application as the root request mapper wrapping the default one:<p class="
 paragraph"/><div class="code"><pre>@Override
+&#125;);</pre></div><p class="paragraph"/>Generated URL:<p class="paragraph"/><div class="code"><pre>&#60;Application path&#62;/mountedPath/foo/foo/bar/bar?1</pre></div><p class="paragraph"/><h3>Encrypting page URLs</h3><p class="paragraph"/>Sometimes URLs are a double–edged sword for our site because they can expose too many details about the internal structure of our web application making it more vulnerable to malicious users.<p class="paragraph"/>To avoid this kind of security threat we can use the <code>CryptoMapper</code> request mapper which wraps an existing mapper and encrypts the original URL producing a single encrypted segment:<p class="paragraph"/><img border="0" class="center" src="../img/url-encrypted.png"></img><p class="paragraph"/>Typically, <code>CryptoMapper</code> is registered into a Wicket application as the root request mapper wrapping the default one:<p class="paragraph"/><div class="code"><pre>@Override
 <span class="java&#45;keyword">public</span> void init() &#123;
 	<span class="java&#45;keyword">super</span>.init();
 	setRootRequestMapper(<span class="java&#45;keyword">new</span> CryptoMapper(getRootRequestMapper(), <span class="java&#45;keyword">this</span>)); 
 	//pages and resources must be mounted after we have set CryptoMapper
-	mountPage(<span class="java&#45;quote">"/foo/"</span>, HomePage.class);</pre></div><p class="paragraph"/>As pointed out in the code above, pages and resources must be mounted after having set CryptoMapper as root mapper, otherwise the mounted paths will not work.
+	mountPage(<span class="java&#45;quote">"/foo/"</span>, HomePage.class);</pre></div><p class="paragraph"/>As pointed out in the code above, pages and resources must be mounted after having set <code>CryptoMapper</code> as root mapper, otherwise the mounted paths will not work.<p class="paragraph"/><blockquote class="warning">
+By default <code>CryptoMapper</code> encrypts page URLs with a cipher that might not be strong enough for production environment. Paragraph 21.4 will provide a more detailed description of how Wicket encrypts page URLs and we will see how to use stronger ciphers.
+</blockquote>
+
 
 
 <h2 id="urls_7">10.7 Summary</h2>
@@ -1818,7 +1825,7 @@ Remember that component model is updated
 <li><strong class="bold">ComponentFeedbackMessageFilter</strong>: shows only messages coming from a specific component.</li>
 <li><strong class="bold">ContainerFeedbackMessageFilter</strong>: shows only messages coming from a specific container or from any of its children components.</li>
 <li><strong class="bold">ErrorLevelFeedbackMessageFilter</strong>: shows only messages with a level of severity equals or greater than a given lower bound. Class FeedbackMessage defines a set of static constants to express different levels of severity: DEBUG, ERROR, WARNING, INFO, SUCCESS, etc.... Levels of severity for feedback messages are discussed in paragraph 10.2.6.</li>
-</ul><p class="paragraph"/>These filters are intended to be used when there are more than one feedback panel (or more than one form) in the same page. We can pass a filter to a feedback panel via its constructor or using the setFilter method. Custom filters can be created implementing the IFeedbackMessageFilter interface. An example of custom filter is illustrated on page 89.<p class="paragraph"/><h3>Built-in validators</h3><p class="paragraph"/>Wicket already provides a number of built-in validators ready to be used. The following table is a short reference where validators are listed along with a brief description of what they do. The default feedback message used by each of them is reported as well:<p class="paragraph"/><h4>EmailAddressValidator</h4><p class="paragraph"/>Checks if input respects the format local-part&#64;domain.<p class="paragraph"/><strong class="bold">Message:</strong><p class="paragraph"/><code>The value of '${label}' is not a valid email address.</code><p cla
 ss="paragraph"/><h4>UrlValidator</h4><p class="paragraph"/>Checks if input is a valid URL. We can specify in the constructor which protocols are allowed (http://, https://, and ftp://).<p class="paragraph"/><strong class="bold">Message:</strong><p class="paragraph"/><code>The value of '${label}' is not a valid URL.</code><p class="paragraph"/><h4>DateValidator</h4><p class="paragraph"/>Validator class that can be extended or used as a factory class to get date validators to check if a date is bigger than a lower bound (method minimum(Date min)), smaller than a upper bound (method maximum(Date max)) or inside a range (method range(Date min, Date max)).<p class="paragraph"/><strong class="bold">Messages:</strong><p class="paragraph"/><code>The value of '${label}' is less than the minimum of ${minimum}.</code><p class="paragraph"/><code>The value of '${label}' is larger than the maximum of ${maximum}.</code><p class="paragraph"/><code>The value of '${label}' is not between ${minimum} a
 nd ${maximum}.</code><p class="paragraph"/><h4>RangeValidator</h4><p class="paragraph"/>Validator class that can be extended or used as a factory class to get validators to check if a value is bigger than a given lower bound (method minimum(T min)), smaller than a upper bound (method maximum(T max)) or inside a range (method range(T min,T max)).<p class="paragraph"/>The type of the value is a generic subtype of java.lang.Comparable and must implement Serializable interface.<p class="paragraph"/><strong class="bold">Messages:</strong><p class="paragraph"/><code>The value of '${label}' must be at least ${minimum}.</code><p class="paragraph"/><code>The value of '${label}' must be at most ${maximum}.</code><p class="paragraph"/><code>The value of '${label}' must be between ${minimum} and ${maximum}.</code><p class="paragraph"/><h4>StringValidator</h4><p class="paragraph"/>Validator class that can be extended or used as a factory class to get validators to check if the length of a string
  value is bigger then a given lower bound (method minimumLength (int min)), smaller then a given upper bound (method maximumLength (int max)) or within a given range (method lengthBetween(int min, int max)).<p class="paragraph"/>To accept only string values consisting of exactly n characters, we must use method exactLength(int length).<p class="paragraph"/><strong class="bold">Messages:</strong><p class="paragraph"/><code>The value of '${label}' is shorter than the minimum of ${minimum} characters.</code><p class="paragraph"/><code>The value of '${label}' is longer than the maximum of ${maximum} characters.</code><p class="paragraph"/><code>The value of '${label}' is not between ${minimum} and ${maximum} characters long.</code><p class="paragraph"/><code>The value of '${label}' is not exactly ${exact} characters long.</code><p class="paragraph"/><h4>CreditCardValidator</h4><p class="paragraph"/>Checks if input is a valid credit card number. This validator supports some of the most p
 opular credit cards (like “American Express", "MasterCard", “Visa” or “Diners Club”).<p class="paragraph"/><strong class="bold">Message:</strong><p class="paragraph"/><code>The credit card number is invalid.</code><p class="paragraph"/><h4>EqualPasswordInputValidator</h4><p class="paragraph"/>This validator checks if two password fields have the same value.<p class="paragraph"/><strong class="bold">Message:</strong><p class="paragraph"/><code>${label0} and ${label1} must be equal.</code><p class="paragraph"/><h3>Overriding standard feedback messages with custom bundles</h3><p class="paragraph"/>If we don't like the default validation feedback messages, we can override them providing custom properties files. In these files we can write our custom messages using the same keys of the messages we want to override. For example if we wanted to override the default message for invalid email addresses, our properties file would contain a line like this:<p class="par
 agraph"/><code>EmailAddressValidator=Man, your email address is not good!</code><p class="paragraph"/>As we will see in the next chapter, Wicket searches for custom properties files in various positions inside the application's class path, but for now we will consider just the properties file placed next to our application class. The name of this file must be equal to the name of our application class:<p class="paragraph"/><img border="0" class="center" src="../img/custom-properties-file.png"></img><p class="paragraph"/>The example project OverrideMailMessage overrides email validator's message with a new one which also reports the value that failed validation:<p class="paragraph"/><code>EmailAddressValidator=The value '${input}' inserted for field '${label}' is not a valid email address.</code><p class="paragraph"/><img border="0" class="center" src="../img/validation-error-message.png"></img><p class="paragraph"/><h3>Creating custom validators</h3><p class="paragraph"/>If our web 
 application requires a complex validation logic and built-in validators are not enough, we can  implement our own custom validators. For example (project UsernameCustomValidator) suppose we are working on the registration page of our site where users can create their profile choosing their username. Our registration form should validate the new username checking if it was already chosen by another user. In a situation like this we may need to implement a custom validator that queries a specific data source to check if a username is already in use.<p class="paragraph"/>For the sake of simplicity, the validator of our example will check the given username against a fixed list of three existing usernames.<p class="paragraph"/>A custom validator must simply implement interface IValidator:<p class="paragraph"/><div class="code"><pre><span class="java&#45;keyword">public</span> class UsernameValidator <span class="java&#45;keyword">implements</span> IValidator&#60;<span class="java&#45;ob
 ject">String</span>&#62; &#123;
+</ul><p class="paragraph"/>These filters are intended to be used when there are more than one feedback panel (or more than one form) in the same page. We can pass a filter to a feedback panel via its constructor or using the setFilter method. Custom filters can be created implementing the IFeedbackMessageFilter interface. An example of custom filter is illustrated later in this paragraph.<p class="paragraph"/><h3>Built-in validators</h3><p class="paragraph"/>Wicket already provides a number of built-in validators ready to be used. The following table is a short reference where validators are listed along with a brief description of what they do. The default feedback message used by each of them is reported as well:<p class="paragraph"/><h4>EmailAddressValidator</h4><p class="paragraph"/>Checks if input respects the format local-part&#64;domain.<p class="paragraph"/><strong class="bold">Message:</strong><p class="paragraph"/><code>The value of '${label}' is not a valid email address.
 </code><p class="paragraph"/><h4>UrlValidator</h4><p class="paragraph"/>Checks if input is a valid URL. We can specify in the constructor which protocols are allowed (http://, https://, and ftp://).<p class="paragraph"/><strong class="bold">Message:</strong><p class="paragraph"/><code>The value of '${label}' is not a valid URL.</code><p class="paragraph"/><h4>DateValidator</h4><p class="paragraph"/>Validator class that can be extended or used as a factory class to get date validators to check if a date is bigger than a lower bound (method minimum(Date min)), smaller than a upper bound (method maximum(Date max)) or inside a range (method range(Date min, Date max)).<p class="paragraph"/><strong class="bold">Messages:</strong><p class="paragraph"/><code>The value of '${label}' is less than the minimum of ${minimum}.</code><p class="paragraph"/><code>The value of '${label}' is larger than the maximum of ${maximum}.</code><p class="paragraph"/><code>The value of '${label}' is not between
  ${minimum} and ${maximum}.</code><p class="paragraph"/><h4>RangeValidator</h4><p class="paragraph"/>Validator class that can be extended or used as a factory class to get validators to check if a value is bigger than a given lower bound (method minimum(T min)), smaller than a upper bound (method maximum(T max)) or inside a range (method range(T min,T max)).<p class="paragraph"/>The type of the value is a generic subtype of java.lang.Comparable and must implement Serializable interface.<p class="paragraph"/><strong class="bold">Messages:</strong><p class="paragraph"/><code>The value of '${label}' must be at least ${minimum}.</code><p class="paragraph"/><code>The value of '${label}' must be at most ${maximum}.</code><p class="paragraph"/><code>The value of '${label}' must be between ${minimum} and ${maximum}.</code><p class="paragraph"/><h4>StringValidator</h4><p class="paragraph"/>Validator class that can be extended or used as a factory class to get validators to check if the lengt
 h of a string value is bigger then a given lower bound (method minimumLength (int min)), smaller then a given upper bound (method maximumLength (int max)) or within a given range (method lengthBetween(int min, int max)).<p class="paragraph"/>To accept only string values consisting of exactly n characters, we must use method exactLength(int length).<p class="paragraph"/><strong class="bold">Messages:</strong><p class="paragraph"/><code>The value of '${label}' is shorter than the minimum of ${minimum} characters.</code><p class="paragraph"/><code>The value of '${label}' is longer than the maximum of ${maximum} characters.</code><p class="paragraph"/><code>The value of '${label}' is not between ${minimum} and ${maximum} characters long.</code><p class="paragraph"/><code>The value of '${label}' is not exactly ${exact} characters long.</code><p class="paragraph"/><h4>CreditCardValidator</h4><p class="paragraph"/>Checks if input is a valid credit card number. This validator supports some 
 of the most popular credit cards (like “American Express", "MasterCard", “Visa” or “Diners Club”).<p class="paragraph"/><strong class="bold">Message:</strong><p class="paragraph"/><code>The credit card number is invalid.</code><p class="paragraph"/><h4>EqualPasswordInputValidator</h4><p class="paragraph"/>This validator checks if two password fields have the same value.<p class="paragraph"/><strong class="bold">Message:</strong><p class="paragraph"/><code>${label0} and ${label1} must be equal.</code><p class="paragraph"/><h3>Overriding standard feedback messages with custom bundles</h3><p class="paragraph"/>If we don't like the default validation feedback messages, we can override them providing custom properties files. In these files we can write our custom messages using the same keys of the messages we want to override. For example if we wanted to override the default message for invalid email addresses, our properties file would contain a line like this:
 <p class="paragraph"/><code>EmailAddressValidator=Man, your email address is not good!</code><p class="paragraph"/>As we will see in the next chapter, Wicket searches for custom properties files in various positions inside the application's class path, but for now we will consider just the properties file placed next to our application class. The name of this file must be equal to the name of our application class:<p class="paragraph"/><img border="0" class="center" src="../img/custom-properties-file.png"></img><p class="paragraph"/>The example project OverrideMailMessage overrides email validator's message with a new one which also reports the value that failed validation:<p class="paragraph"/><code>EmailAddressValidator=The value '${input}' inserted for field '${label}' is not a valid email address.</code><p class="paragraph"/><img border="0" class="center" src="../img/validation-error-message.png"></img><p class="paragraph"/><h3>Creating custom validators</h3><p class="paragraph"
 />If our web application requires a complex validation logic and built-in validators are not enough, we can  implement our own custom validators. For example (project UsernameCustomValidator) suppose we are working on the registration page of our site where users can create their profile choosing their username. Our registration form should validate the new username checking if it was already chosen by another user. In a situation like this we may need to implement a custom validator that queries a specific data source to check if a username is already in use.<p class="paragraph"/>For the sake of simplicity, the validator of our example will check the given username against a fixed list of three existing usernames.<p class="paragraph"/>A custom validator must simply implement interface IValidator:<p class="paragraph"/><div class="code"><pre><span class="java&#45;keyword">public</span> class UsernameValidator <span class="java&#45;keyword">implements</span> IValidator&#60;<span class
 ="java&#45;object">String</span>&#62; &#123;
 	List&#60;<span class="java&#45;object">String</span>&#62; existingUsernames = Arrays.asList(<span class="java&#45;quote">"bigJack"</span>, <span class="java&#45;quote">"anonymous"</span>, <span class="java&#45;quote">"mrSmith"</span>);<p class="paragraph"/>	<span class="java&#45;keyword">public</span> void validate(IValidatable&#60;<span class="java&#45;object">String</span>&#62; validatable) &#123;
 		<span class="java&#45;object">String</span> chosenUserName = validatable.getValue();<p class="paragraph"/>		<span class="java&#45;keyword">if</span>(existingUsernames.contains(chosenUserName))&#123;
 			ValidationError error = <span class="java&#45;keyword">new</span> ValidationError(<span class="java&#45;keyword">this</span>);
@@ -1865,7 +1872,9 @@ Remember that component model is updated
 		&#125;<p class="paragraph"/>    &#125;
     //UsernameValidator definition
     //&#8230;
-&#125;</pre></div><p class="paragraph"/>The two feedback panels must be filtered in order to display just the messages with a given level of severity (ERROR for validator message and SUCCESS for form's flash message). Unfortunately the built-in message filter ErrorLevelFeedbackMessageFilter is not suitable for this task because its filter condition does not check for an exact error level (the given level is used as lower bound value). As a consequence, we had to build a custom filter (inner class ExactErrorLevelFilter) to accept only the desired severity level (see method accept of interface IFeedbackMessageFilter). 
+&#125;</pre></div><p class="paragraph"/>The two feedback panels must be filtered in order to display just the messages with a given level of severity (ERROR for validator message and SUCCESS for form's flash message). Unfortunately the built-in message filter ErrorLevelFeedbackMessageFilter is not suitable for this task because its filter condition does not check for an exact error level (the given level is used as lower bound value). As a consequence, we had to build a custom filter (inner class ExactErrorLevelFilter) to accept only the desired severity level (see method accept of interface IFeedbackMessageFilter).<p class="paragraph"/><blockquote class="note">
+Since version 6.13.0 Wicket provides the additional filter class org.apache.wicket.feedback.ExactLevelFeedbackMessageFilter to accept only feedback messages of a certain error level.
+</blockquote><p class="paragraph"/>
 
 
 <h2 id="forms2_3">12.3 Input value conversion</h2>
@@ -2307,9 +2316,9 @@ A common task for web applications is to
 <div class="code"><pre>&#60;ul&#62;
     &#60;li wicket:id=<span class="java&#45;quote">"listItems"</span>&#62;&#60;/li&#62;
 &#60;/ul&#62;</pre></div><p class="paragraph"/><strong class="bold">Java Code:</strong>
-<div class="code"><pre>RepeatingView listItems = <span class="java&#45;keyword">new</span> RepeatingView(<span class="java&#45;quote">"listItems"</span>);<p class="paragraph"/>listItems.add(<span class="java&#45;keyword">new</span> Label(listItems.newChildId(), <span class="java&#45;quote">"green"</span>);
-listItems.add(<span class="java&#45;keyword">new</span> Label(listItems.newChildId(), <span class="java&#45;quote">"blue"</span>);
-listItems.add(<span class="java&#45;keyword">new</span> Label(listItems.newChildId(), <span class="java&#45;quote">"red"</span>);</pre></div><p class="paragraph"/><strong class="bold">Generated markup:</strong>
+<div class="code"><pre>RepeatingView listItems = <span class="java&#45;keyword">new</span> RepeatingView(<span class="java&#45;quote">"listItems"</span>);<p class="paragraph"/>listItems.add(<span class="java&#45;keyword">new</span> Label(listItems.newChildId(), <span class="java&#45;quote">"green"</span>));
+listItems.add(<span class="java&#45;keyword">new</span> Label(listItems.newChildId(), <span class="java&#45;quote">"blue"</span>));
+listItems.add(<span class="java&#45;keyword">new</span> Label(listItems.newChildId(), <span class="java&#45;quote">"red"</span>));</pre></div><p class="paragraph"/><strong class="bold">Generated markup:</strong>
 <div class="code"><pre>&#60;ul&#62;
     &#60;li&#62;green&#60;/li&#62;
     &#60;li&#62;blue&#60;/li&#62;
@@ -2317,6 +2326,7 @@ listItems.add(<span class="java&#45;keyw
 &#60;/ul&#62;</pre></div><p class="paragraph"/>As we can see in this example, each child component has been rendered using the parent markup as if it was its own.
 
 
+
 <h2 id="repeaters_2">13.2 The ListView Component</h2>
 <p class="paragraph"/>As its name suggests, component <code>org.apache.wicket.markup.html.list.ListView</code> is designed to display a given list of objects which can be provided as a standard Java List or as a model containing the concrete List. ListView iterates over the list and creates a child component of type <code>org.apache.wicket.markup.html.list.ListItem</code> for every encountered item.<p class="paragraph"/>Unlike RepeatingView this component is intended to be used with complex markup fragments containing nested components.<p class="paragraph"/>To generate its children, ListView calls its abstract method populateItem(ListItem&#60;T&#62; item) for each item in the list, so we must provide an implementation of this method to tell the component how to create its children components. In the following example we use a ListView to display a list of Person objects:<p class="paragraph"/><strong class="bold">HTML:</strong>
 <div class="code"><pre>&#8230;
@@ -2471,7 +2481,8 @@ If you want to use UTF-8 with your text
 	&#125;
 &#125;;<p class="paragraph"/>setStatelessHint(<span class="java&#45;keyword">true</span>);
 add(form.add(changeLocale))</pre></div><p class="paragraph"/>
-<h3>Localization of markup files</h3><p class="paragraph"/>Although resource bundles exist to extract local-dependent elements from our code and from UI components, in Wicket we can decide to provide different markup files for different locale settings. Just like standard markup files, by default localized markup files must be placed next to component's class and their file name must contain the locale's informations. In the following picture, CustomPanel comes with a standard (or default) markup file and with another one localized for German:<p class="paragraph"/><img border="0" class="center" src="../img/comp-with-markup-german.png"></img><p class="paragraph"/>When the current locale corresponds to German country (language code de), markup file CustomPanel_de.html will be used in place of the default one.<p class="paragraph"/><h3>Reading bundles with tag &#60;wicket:message&#62;</h3><p class="paragraph"/>String resources can be also retrieved directly from markup code using tag &#
 60;wicket:message&#62;. The key of the desired resource is specified with attribute key:<p class="paragraph"/><div class="code"><pre><span class="xml&#45;tag">&#60;wicket:message key=<span class="xml&#45;quote">"greetingMessage"</span>&#62;</span>message goes here<span class="xml&#45;tag">&#60;/wicket:message&#62;</span></pre></div><p class="paragraph"/>wicket:message can be adopted also to localize the attributes of a tag. The name of the attribute and the resource key are expressed as a colon-separated value. In the following markup the content of attribute value will be replaced with the localized resource having 'key4value' as key:<p class="paragraph"/><div class="code"><pre>&#60;input type=<span class="java&#45;quote">"submit"</span> value=<span class="java&#45;quote">"Preview value"</span> wicket:message=<span class="java&#45;quote">"value:key4value"</span>/&#62;</pre></div><p class="paragraph"/>If we want to specify multiple attributes at once, we can separate them with a com
 a:<p class="paragraph"/><div class="code"><pre>&#60;input type=<span class="java&#45;quote">"submit"</span> value=<span class="java&#45;quote">"Preview value"</span> wicket:message=<span class="java&#45;quote">"value:key4value, title:key4title"</span>/&#62;</pre></div>
+<h3>Localization of markup files</h3><p class="paragraph"/>Although resource bundles exist to extract local-dependent elements from our code and from UI components, in Wicket we can decide to provide different markup files for different locale settings. Just like standard markup files, by default localized markup files must be placed next to component's class and their file name must contain the locale's informations. In the following picture, CustomPanel comes with a standard (or default) markup file and with another one localized for German:<p class="paragraph"/><img border="0" class="center" src="../img/comp-with-markup-german.png"></img><p class="paragraph"/>When the current locale corresponds to German country (language code de), markup file CustomPanel_de.html will be used in place of the default one.<p class="paragraph"/><h3>Reading bundles with tag &#60;wicket:message&#62;</h3><p class="paragraph"/>String resources can be also retrieved directly from markup code using tag &#
 60;wicket:message&#62;. The key of the desired resource is specified with attribute key:<p class="paragraph"/><div class="code"><pre><span class="xml&#45;tag">&#60;wicket:message key=<span class="xml&#45;quote">"greetingMessage"</span>&#62;</span>message goes here<span class="xml&#45;tag">&#60;/wicket:message&#62;</span></pre></div><p class="paragraph"/>By default the resource value is not escaped for HTML entities. To do that use the <code>escape</code> attribute:<p class="paragraph"/><div class="code"><pre><span class="xml&#45;tag">&#60;wicket:message key=<span class="xml&#45;quote">"greetingMessage"</span> escape=<span class="xml&#45;quote">"true"</span>&#62;</span>message goes here<span class="xml&#45;tag">&#60;/wicket:message&#62;</span></pre></div><p class="paragraph"/>
+<code>wicket:message</code> can be adopted also to localize the attributes of a tag. The name of the attribute and the resource key are expressed as a colon-separated value. In the following markup the content of attribute <code>value</code> will be replaced with the localized resource having 'key4value' as key:<p class="paragraph"/><div class="code"><pre>&#60;input type=<span class="java&#45;quote">"submit"</span> value=<span class="java&#45;quote">"Preview value"</span> wicket:message=<span class="java&#45;quote">"value:key4value"</span>/&#62;</pre></div><p class="paragraph"/>If we want to specify multiple attributes at once, we can separate them with a comma:<p class="paragraph"/><div class="code"><pre>&#60;input type=<span class="java&#45;quote">"submit"</span> value=<span class="java&#45;quote">"Preview value"</span> wicket:message=<span class="java&#45;quote">"value:key4value, title:key4title"</span>/&#62;</pre></div>
 
 
 
@@ -2943,8 +2954,20 @@ In this chapter we will learn some advan
 	&#125;<p class="paragraph"/>	<span class="java&#45;keyword">final</span> RequestListenerInterface rli;<p class="paragraph"/>	rli = IBehaviorListener.INTERFACE;<p class="paragraph"/>	<span class="java&#45;keyword">return</span> boundComponent.urlFor(<span class="java&#45;keyword">this</span>, rli, <span class="java&#45;keyword">new</span> PageParameters());
 &#125;</pre></div><p class="paragraph"/>Static field <code>IBehaviorListener.INTERFACE</code> is the implementation of <code>RequestListenerInterface</code> defined inside callback interface <code>IBehaviorListener</code>.<p class="paragraph"/>The home page of project <code>CallbackURLExample</code> contains a <code>DropDownChoice</code> and a <code>RadioChoice</code> which use our custom behavior. There are also two labels to display the content of the models of the two components:<p class="paragraph"/><img border="0" class="center" src="../img/CallbackURLExample-screenshot.png"></img><p class="paragraph"/><blockquote class="note">
 Implementing interface <code>IBehaviorListener</code> makes a behavior stateful because its callback URL is specific for a given instance of component.
-</blockquote><p class="paragraph"/>
-<h3>Wicket events infrastructure</h3><p class="paragraph"/>Starting from version 1.5 Wicket offers an event-based infrastructure for inter-component communication. The infrastructure is based on two simple interfaces (both in package <code>org.apache.wicket.event</code>) : <code>IEventSource</code> and <code>IEventSink</code>.<p class="paragraph"/>The first interface must be implemented by those entities that want to broadcast en event while the second interface must be implemented by those entities that want to receive a broadcast event.<p class="paragraph"/>The following entities already implement both these two interfaces (i.e. they can be either sender or receiver): <code>Component</code>, <code>Session</code>, <code>RequestCycle</code> and <code>Application</code>.
+</blockquote><p class="paragraph"/>As final note it's interesting to see how Wicket internally uses callback URLs for its standard link component. Class <code>org.apache.wicket.markup.html.link.Link</code> implements interface <code>org.apache.wicket.markup.html.link.ILinkListener</code> which in turn extends <code>IRequestListener</code>:<p class="paragraph"/><div class="code"><pre><span class="java&#45;keyword">public</span> <span class="java&#45;keyword">interface</span> ILinkListener <span class="java&#45;keyword">extends</span> IRequestListener
+&#123;
+	/&#42;&#42; Listener <span class="java&#45;keyword">interface</span> &#42;/
+	<span class="java&#45;keyword">public</span> <span class="java&#45;keyword">static</span> <span class="java&#45;keyword">final</span> RequestListenerInterface INTERFACE = <span class="java&#45;keyword">new</span> RequestListenerInterface(
+		ILinkListener.class);<p class="paragraph"/>	/&#42;&#42;
+	 &#42; Called when a link is clicked.
+	 &#42;/
+	void onLinkClicked();
+&#125;</pre></div><p class="paragraph"/>The implementation of method <code>onLinkClicked</code> simply delegates event handling to our custom version of <code>onClick</code>:<p class="paragraph"/><div class="code"><pre>@Override
+<span class="java&#45;keyword">public</span> <span class="java&#45;keyword">final</span> void onLinkClicked()
+&#123;
+	// Invoke subclass handler
+	onClick();
+&#125;</pre></div><p class="paragraph"/><h3>Wicket events infrastructure</h3><p class="paragraph"/>Starting from version 1.5 Wicket offers an event-based infrastructure for inter-component communication. The infrastructure is based on two simple interfaces (both in package <code>org.apache.wicket.event</code>) : <code>IEventSource</code> and <code>IEventSink</code>.<p class="paragraph"/>The first interface must be implemented by those entities that want to broadcast en event while the second interface must be implemented by those entities that want to receive a broadcast event.<p class="paragraph"/>The following entities already implement both these two interfaces (i.e. they can be either sender or receiver): <code>Component</code>, <code>Session</code>, <code>RequestCycle</code> and <code>Application</code>.
 <code>IEventSource</code> exposes a single method named send which takes in input three parameters:
 <ul class="star">
 <li><strong class="bold">sink</strong>: an implementation of <code>IEventSink</code> that will be the receiver of the event.</li>
@@ -3257,7 +3280,10 @@ dynamicLabel.add(<span class="java&#45;k
 		//...				
 	&#125;
 &#125;);
-add(dynamicLabel);</pre></div>
+add(dynamicLabel);</pre></div><p class="paragraph"/><blockquote class="note">
+As side effect AJAX components and behaviors make their hosting page stateful. As a consequence they are unfit for those pages that must stay stateless. Project WicketStuff provides a module with a stateless version of the most common AJAX components and behaviors. You can find more informations on this module in Appendix B. 
+</blockquote>
+
 
 
 <h2 id="ajax_4">18.4 Using an activity indicator</h2>
@@ -3777,7 +3803,7 @@ Application class <code>AuthenticatedWeb
 
 
 <h2 id="security_3">21.3 Using HTTPS protocol</h2>
-<p class="paragraph"/>HTTPS is the standard technology adopted on Internet to create a secure communication channel between web applications and their users.<p class="paragraph"/>In Wicket we can easily protect our pages with HTTPS mounting a special request mapper called <code>HttpsMapper</code> and using annotation RequireHttps with those pages we want to serve over this protocol. Both these two entities are in package <code>org.apache.wicket.protocol.https</code>.<p class="paragraph"/>HttpsMapper wraps an existing mapper and redirects incoming requests to HTTPS if the related response must render a page containing annotation <code>RequireHttps</code>. Most of the times the wrapped mapper will be the root one, just like we saw before for <code>CryptoManager</code> in paragraph 8.6.6.<p class="paragraph"/>Another parameter needed to build a <code>HttpsMapper</code> is an instance of class <code>HttpsConfi</code>g. This class allows us to specify which ports must be used for HTTPS a
 nd HTTP. By default the port numbers used by these two protocols are respectively 443 and 80.<p class="paragraph"/>The following code is taken from project <code>HttpsProtocolExample</code> and illustrates how to enable HTTPS  in our applications:<p class="paragraph"/><div class="code"><pre>//Application class code&#8230;
+<p class="paragraph"/>HTTPS is the standard technology adopted on Internet to create a secure communication channel between web applications and their users.<p class="paragraph"/>In Wicket we can easily protect our pages with HTTPS mounting a special request mapper called <code>HttpsMapper</code> and using annotation RequireHttps with those pages we want to serve over this protocol. Both these two entities are in package <code>org.apache.wicket.protocol.https</code>.<p class="paragraph"/>HttpsMapper wraps an existing mapper and redirects incoming requests to HTTPS if the related response must render a page containing annotation <code>RequireHttps</code>. Most of the times the wrapped mapper will be the root one, just like we saw before for <code>CryptoMapper</code> in paragraph 10.6.<p class="paragraph"/>Another parameter needed to build a <code>HttpsMapper</code> is an instance of class <code>HttpsConfi</code>g. This class allows us to specify which ports must be used for HTTPS and
  HTTP. By default the port numbers used by these two protocols are respectively 443 and 80.<p class="paragraph"/>The following code is taken from project <code>HttpsProtocolExample</code> and illustrates how to enable HTTPS  in our applications:<p class="paragraph"/><div class="code"><pre>//Application class code&#8230;
 @Override
 <span class="java&#45;keyword">public</span> void init()&#123;   
    setRootRequestMapper(<span class="java&#45;keyword">new</span> HttpsMapper(getRootRequestMapper(), 
@@ -3803,7 +3829,40 @@ Application class <code>AuthenticatedWeb
 &#125;</pre></div>
 
 
-<h2 id="security_4">21.4 Package Resource Guard</h2>
+
+<h2 id="security_4">21.4 URLs encryption in detail</h2>
+In chapter <a href="../guide/single.html#urls_6" class="guide">10.6</a> we have seen how to encrypt URLs using <code>CryptoMapper</code> request mapper. To encrypt/decrypt page URLs <code>CryptoMapper</code> uses an instance of <code>org.apache.wicket.util.crypt.ICrypt</code> interface:<p class="paragraph"/><div class="code"><pre><span class="java&#45;keyword">public</span> <span class="java&#45;keyword">interface</span> ICrypt
+&#123;
+	<span class="java&#45;object">String</span> encryptUrlSafe(<span class="java&#45;keyword">final</span> <span class="java&#45;object">String</span> plainText);<p class="paragraph"/>	<span class="java&#45;object">String</span> decryptUrlSafe(<span class="java&#45;keyword">final</span> <span class="java&#45;object">String</span> encryptedText);<p class="paragraph"/>	&#8230;
+&#125;</pre></div><p class="paragraph"/>The default implementation for this interface is class <code>org.apache.wicket.util.crypt.SunJceCrypt</code>. It provides password-based cryptography using <code>PBEWithMD5AndDES</code> algorithm coming with the standard security providers in the Java Runtime Environment.<p class="paragraph"/><blockquote class="note">
+For better security it is recommended to install Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction <a href="http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html" target="blank">Policy Files</a> for your version of JDK/JRE and use stronger algorithms. See this <a href="https://github.com/apache/wicket/blob/42ce1faa57d3617ccaa443045537306fabf4d71a/wicket-util/src/test/java/org/apache/wicket/util/crypt/UnlimitedStrengthJurisdictionPolicyTest.java#L67" target="blank">example</a> of a custom <code>ICrypt</code> implementation for inspiration.
+</blockquote><p class="paragraph"/>By using <code>CryptoMapper(IRequestMapper wrappedMapper, Application application)</code> constructor the mapper will use the configured <code>org.apache.wicket.util.crypt.ICryptFactory</code> from <code>org.apache.wicket.settings.ISecuritySettings#getCryptFactory()</code>. To use a stronger cryptography mechanism there are the following options:
+<ul class="star">
+<li>The first option is to use constructor <code>CryptoMapper(IRequestMapper wrappedMapper, IProvider&#60;ICrypt&#62; cryptProvider)</code> and give it an implementation of <code>org.apache.wicket.util.IProvider</code> that returns a custom <code>org.apache.wicket.util.crypt.ICrypt</code>.</li>
+</ul><p class="paragraph"/><blockquote class="note">
+<code>org.apache.wicket.util.IProvider</code> is a single-method interface that acts as object supplier:
+</blockquote><p class="paragraph"/><div class="code"><pre><span class="java&#45;keyword">public</span> <span class="java&#45;keyword">interface</span> IProvider&#60;T&#62;
+&#123;
+	T get();
+&#125;</pre></div>
+<ul class="star">
+<li>The second option is to register a cipher factory at application level with method <code>setCryptFactory(ICryptFactory cryptFactory)</code> of interface <code>ISecuritySettings</code>:</li>
+</ul><p class="paragraph"/><div class="code"><pre>@Override
+<span class="java&#45;keyword">public</span> void init() &#123;
+	<span class="java&#45;keyword">super</span>.init();
+	getSecuritySettings().setCryptFactory(<span class="java&#45;keyword">new</span> SomeCryptFactory());
+	setRootRequestMapper(<span class="java&#45;keyword">new</span> CryptoMapper(getRootRequestMapper(), <span class="java&#45;keyword">this</span>));
+&#125;</pre></div><p class="paragraph"/>
+Since version 6.19.0 Wicket uses <code>org.apache.wicket.core.util.crypt.KeyInSessionSunJceCryptFactory</code> as a default factory for <code>ICrypt</code> objects. This factory generates a unique key for each user that is stored in her HTTP 
+session. This way it helps to protect the application against <a href="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)" target="blank">CSRF</a> attacks - the &#60;form&#62; action url will be encrypted in such way that it will be unique
+for each user of the application. The url itself serves as <a href="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet#Encrypted_Token_Pattern" target="blank">encrypted token</a>.<p class="paragraph"/><blockquote class="warning">
+<code>org.apache.wicket.core.util.crypt.KeyInSessionSunJceCryptFactory</code> binds the http session if it is not already bound! If the application needs to run in stateless mode then the application will have to provide a custom 
+implementation of <code>ICryptFactory</code> that stores the user specific keys by other means.
+</blockquote>
+
+
+
+<h2 id="security_5">21.5 Package Resource Guard</h2>
 <p class="paragraph"/>Wicket internally uses an entity called package resource guard to protect package resources from external access. This entity is an implementation of interface <code>org.apache.wicket.markup.html.IPackageResourceGuard</code>.<p class="paragraph"/>By default Wicket applications use as package resource guard class <code>SecurePackageResourceGuard</code>, which allows to access only to the following file extensions (grouped by type):<p class="paragraph"/><table class="wiki-table" cellpadding="0" cellspacing="0" border="0"><tr><th>File</th><th>Extensions</th></tr><tr class="table-odd"><td><strong class="bold">JavaScript files</strong></td><td>.js</td></tr><tr class="table-even"><td><strong class="bold">CSS files</strong></td><td>.css</td></tr><tr class="table-odd"><td><strong class="bold">HTML pages</strong></td><td>.html</td></tr><tr class="table-even"><td><strong class="bold">Textual files</strong></td><td>.txt</td></tr><tr class="table-odd"><td><strong class="bo
 ld">Flash files</strong></td><td>.swf</td></tr><tr class="table-even"><td><strong class="bold">Picture files</strong></td><td>.png, .jpg, .jpeg, .gif, .ico, .cur, .bmp, .svg</td></tr><tr class="table-odd"><td><strong class="bold">Web font files</strong></td><td>.eot, .ttf, .woff</td></tr></table><p class="paragraph"/>To modify the set of allowed files formats we can add one or more patterns with method <code>addPattern(String)</code>. The rules to write a pattern are the following:
 <ul class="star">
 <li>patterns start with either a "+" or a "-". In the first case the pattern will add one or more file to the set while starting a pattern with a “-” we exclude all the files matching the given pattern. For example pattern “-web.xml” excludes all web.xml files in all directories.</li>
@@ -3826,7 +3885,7 @@ Application class <code>AuthenticatedWeb
 
 
 
-<h2 id="security_5">21.5 Summary</h2>
+<h2 id="security_6">21.6 Summary</h2>
 <p class="paragraph"/> In this chapter we have seen the components and the mechanisms that allow us to implement security policies in our Wicket-based applications. Wicket comes with an out of the box support for both authorization and authentication.<p class="paragraph"/>The central element of authorization mechanism is the interface <code>IAuthorizationStrategy</code> which decouples our components from any detail about security strategy. The implementations of this interface must decide if a user is allowed to instantiate a given page or component and if she/he can perform a given action on it.<p class="paragraph"/>Wicket natively supports role-based authorizations with strategies <code>MetaDataRoleAuthorizationStrategy</code> and <code>AnnotationsRoleAuthorizationStrategy</code>. The difference between these two strategies is that the first offers a programmatic approach for role handling while the second promotes a declarative approach using built-in annotations.<p class="parag
 raph"/>After having explored how Wicket internally implements authentication and authorization, in the last part of the chapter we have learnt how to configure our applications to support HTTPS and how to specify which pages must be served over this protocol.<p class="paragraph"/>In the last paragraph we have seen how Wicket protects package resources with a guard entity that allows us to decide which package resources can be accessed from users.<p class="paragraph"/><p class="paragraph"/>
 
 
@@ -4708,6 +4767,12 @@ To write/read objects to response/from r
 
 
 
+<h2 id="wicketstuff_7">27.7 Module stateless</h2>
+Wicket makes working with AJAX easy and pleasant with its component-oriented abstraction. However as side effect, AJAX components and behaviors make their hosting page stateful. This can be quite annoying if we are working on a page that must be stateless (for example a login page). 
+In this case an obvious solution would be to roll out our own stateless components/behaviors, but Wicketstuff alredy offers such kind of artifacts with <code>stateless</code> module. Here you can find the stateless version of the basic AJAX componets and behaviors shiped with Wicket, like <code>StatelessAjaxSubmitLink</code>, <code>StatelessAjaxFallbackLink</code>, <code>StatelessAjaxEventBehavior</code>, <code>StatelessAjaxFormSubmitBehavior</code> etc&#8230;
+A short introduction to this module can be found on its <a href="https://github.com/wicketstuff/core/tree/master/jdk-1.7-parent/stateless-parent" target="blank">home page</a> .<p class="paragraph"/>
+
+
 <h1 id="redirects">28 Lost In Redirection With Apache Wicket (Appendix)</h1>
 Quite a few teams have already got stuck into the following problem when working with wicket forms in a clustered environment while having 2 (or more) tomcat server with enabled session replication running.<p class="paragraph"/>In case of invalid data being submitted with a form instance for example, it seemed like according error messages wouldn’t be presented when the same form page gets displayed again. Sometimes! And sometimes they would! One of those nightmares of rather deterministic programmer’s life. This so called Lost In Redirection problem, even if it looks like a wicket bug at first, is rather a result of a default setting in wicket regarding the processing of form submissions in general. In order to prevent another wide known problem of double form submissions, Wicket uses a so called REDIRECT_TO_BUFFER strategy for dealing with rendering a page after web form’s processing (@see IRequestCycleSettings#RenderStrategy).<p class="paragraph"/>What does the def
 ault RenderStrategy actually do?<p class="paragraph"/>Both logical parts of a single HTTP request, an action and a render part get processed within the same request, but instead of streaming the render result to the browser directly, the result is cached on the server first.<p class="paragraph"/><img border="0" class="center" src="../img/lost-in-redirection-mockup.png"></img><p class="paragraph"/>Wicket will create an according BufferedHttpServletResponse instance that will be used to cache the resulting HttpServletResponse within the WebApplication.<p class="paragraph"/><img border="0" class="center" src="../img/lost-in-redirection-mockup2.png"></img><p class="paragraph"/>After the buffered response is cached the HTTP status code of 302 get’s provided back to the browser resulting in an additional GET request to the redirect URL (which Wicket sets to the URL of the Form itself). There is a special handling code for this case in the WicketFilter instance that then looks up a Ma
 p of buffered responses within the WebApplication accordingly. If an appropriate already cached response for the current request is found, it get’s streamed back to the browser immediately. No additional form processing happens now. The following is a code snippet taken from WicketFilter:<p class="paragraph"/><div class="code"><pre>// Are we using REDIRECT_TO_BUFFER?
 <span class="java&#45;keyword">if</span> (webApplication.getRequestCycleSettings().getRenderStrategy() == IRequestCycleSettings.REDIRECT_TO_BUFFER)
@@ -4790,7 +4855,7 @@ and attach it to a ticket in Apache Wick
         <div id="footer">
             
 Copyright &copy; 2013-2014 — <a href="http://www.apache.org/" target="_blank">The Apache Software Foundation</a> 
-                      — <b style="color:#E8590A !important;">(Generated on: 2014-11-11)</b>
+                      — <b style="color:#E8590A !important;">(Generated on: 2015-02-03)</b>
 
             
         </div>

Modified: wicket/common/site/trunk/_site/guide/guide/testing.html
URL: http://svn.apache.org/viewvc/wicket/common/site/trunk/_site/guide/guide/testing.html?rev=1656683&r1=1656682&r2=1656683&view=diff
==============================================================================
--- wicket/common/site/trunk/_site/guide/guide/testing.html (original)
+++ wicket/common/site/trunk/_site/guide/guide/testing.html Tue Feb  3 11:19:18 2015
@@ -430,7 +430,7 @@ formTester.submit(<span class="java&#45;
 <div id="footer">
     
 Copyright &copy; 2013-2014 — <a href="http://www.apache.org/" target="_blank">The Apache Software Foundation</a> 
-                      — <b style="color:#E8590A !important;">(Generated on: 2014-11-11)</b>
+                      — <b style="color:#E8590A !important;">(Generated on: 2015-02-03)</b>
 
     
 </div>

Modified: wicket/common/site/trunk/_site/guide/guide/testingspring.html
URL: http://svn.apache.org/viewvc/wicket/common/site/trunk/_site/guide/guide/testingspring.html?rev=1656683&r1=1656682&r2=1656683&view=diff
==============================================================================
--- wicket/common/site/trunk/_site/guide/guide/testingspring.html (original)
+++ wicket/common/site/trunk/_site/guide/guide/testingspring.html Tue Feb  3 11:19:18 2015
@@ -324,7 +324,7 @@ Since the development of many web applic
 <div id="footer">
     
 Copyright &copy; 2013-2014 — <a href="http://www.apache.org/" target="_blank">The Apache Software Foundation</a> 
-                      — <b style="color:#E8590A !important;">(Generated on: 2014-11-11)</b>
+                      — <b style="color:#E8590A !important;">(Generated on: 2015-02-03)</b>
 
     
 </div>

Modified: wicket/common/site/trunk/_site/guide/guide/urls.html
URL: http://svn.apache.org/viewvc/wicket/common/site/trunk/_site/guide/guide/urls.html?rev=1656683&r1=1656682&r2=1656683&view=diff
==============================================================================
--- wicket/common/site/trunk/_site/guide/guide/urls.html (original)
+++ wicket/common/site/trunk/_site/guide/guide/urls.html Tue Feb  3 11:19:18 2015
@@ -331,12 +331,15 @@ setResponsePage(MountedPageWithPlacehold
 		pageParameters.add(<span class="java&#45;quote">"foo"</span>, <span class="java&#45;quote">"foo"</span>);
 		pageParameters.add(<span class="java&#45;quote">"bar"</span>, <span class="java&#45;quote">"bar"</span>);<p class="paragraph"/>		setResponsePage(MountedPage.class, pageParameters);
 	&#125;
-&#125;);</pre></div><p class="paragraph"/>Generated URL:<p class="paragraph"/><div class="code"><pre>&#60;Application path&#62;/mountedPath/foo/foo/bar/bar?1</pre></div><p class="paragraph"/><h3>Encrypting page URLs</h3><p class="paragraph"/>Sometimes URLs are a double–edged sword for our site because they can expose too many details about the internal structure of our web application and malicious users could exploit them to perform a <a href="http://en.wikipedia.org/wiki/Cross-site_request_forgery" target="blank">cross-site request forgery</a> .<p class="paragraph"/>To avoid this kind of security threat we can use the CryptoMapper request mapper which wraps an existing mapper and encrypts the original URL producing a single encrypted segment:<p class="paragraph"/><img border="0" class="center" src="../img/url-encrypted.png"></img><p class="paragraph"/>Typically, CryptoMapper is registered into a Wicket application as the root request mapper wrapping the default one:<p class="
 paragraph"/><div class="code"><pre>@Override
+&#125;);</pre></div><p class="paragraph"/>Generated URL:<p class="paragraph"/><div class="code"><pre>&#60;Application path&#62;/mountedPath/foo/foo/bar/bar?1</pre></div><p class="paragraph"/><h3>Encrypting page URLs</h3><p class="paragraph"/>Sometimes URLs are a double–edged sword for our site because they can expose too many details about the internal structure of our web application making it more vulnerable to malicious users.<p class="paragraph"/>To avoid this kind of security threat we can use the <code>CryptoMapper</code> request mapper which wraps an existing mapper and encrypts the original URL producing a single encrypted segment:<p class="paragraph"/><img border="0" class="center" src="../img/url-encrypted.png"></img><p class="paragraph"/>Typically, <code>CryptoMapper</code> is registered into a Wicket application as the root request mapper wrapping the default one:<p class="paragraph"/><div class="code"><pre>@Override
 <span class="java&#45;keyword">public</span> void init() &#123;
 	<span class="java&#45;keyword">super</span>.init();
 	setRootRequestMapper(<span class="java&#45;keyword">new</span> CryptoMapper(getRootRequestMapper(), <span class="java&#45;keyword">this</span>)); 
 	//pages and resources must be mounted after we have set CryptoMapper
-	mountPage(<span class="java&#45;quote">"/foo/"</span>, HomePage.class);</pre></div><p class="paragraph"/>As pointed out in the code above, pages and resources must be mounted after having set CryptoMapper as root mapper, otherwise the mounted paths will not work.
+	mountPage(<span class="java&#45;quote">"/foo/"</span>, HomePage.class);</pre></div><p class="paragraph"/>As pointed out in the code above, pages and resources must be mounted after having set <code>CryptoMapper</code> as root mapper, otherwise the mounted paths will not work.<p class="paragraph"/><blockquote class="warning">
+By default <code>CryptoMapper</code> encrypts page URLs with a cipher that might not be strong enough for production environment. Paragraph 21.4 will provide a more detailed description of how Wicket encrypts page URLs and we will see how to use stronger ciphers.
+</blockquote>
+
 
 
 <h2 id="urls_7">10.7 Summary</h2>
@@ -369,7 +372,7 @@ setResponsePage(MountedPageWithPlacehold
 <div id="footer">
     
 Copyright &copy; 2013-2014 — <a href="http://www.apache.org/" target="_blank">The Apache Software Foundation</a> 
-                      — <b style="color:#E8590A !important;">(Generated on: 2014-11-11)</b>
+                      — <b style="color:#E8590A !important;">(Generated on: 2015-02-03)</b>
 
     
 </div>

Modified: wicket/common/site/trunk/_site/guide/guide/versioningCaching.html
URL: http://svn.apache.org/viewvc/wicket/common/site/trunk/_site/guide/guide/versioningCaching.html?rev=1656683&r1=1656682&r2=1656683&view=diff
==============================================================================
--- wicket/common/site/trunk/_site/guide/guide/versioningCaching.html (original)
+++ wicket/common/site/trunk/_site/guide/guide/versioningCaching.html Tue Feb  3 11:19:18 2015
@@ -210,12 +210,12 @@ For more details about page storing you
 </blockquote><p class="paragraph"/>As we have stated at the beginning of this chapter, page versions are stored using Java serialization, therefore every object referenced inside a page must be serializable. In paragraph 9.6 we will see how to overcome this limit and work with non-serializable objects in our components using detachable Wicket models.<p class="paragraph"/><h3>Using a specific page version with PageReference</h3><p class="paragraph"/>To retrieve a specific page version in our code we can use class <code>org.apache.wicket.PageReference</code> by providing its constructor with the corresponding page id:<p class="paragraph"/><div class="code"><pre>//load page version with page id = 3
 PageReference pageReference = <span class="java&#45;keyword">new</span> PageReference(3);
 //load the related page instance
-Page page = pageReference.getPage();</pre></div><p class="paragraph"/>To get the related page instance we must use method getPage.<p class="paragraph"/><h3>Turning off page versioning</h3><p class="paragraph"/>If for any reason we need to switch off versioning for a given page, we can call its method setVersioned(false).<p class="paragraph"/><h3>Pluggable serialization</h3><p class="paragraph"/>Starting from version 1.5 it is possible to choose which implementation of Java serialization will be used by Wicket to store page versions. Wicket serializes pages using an implementation of interface <code>org.apache.wicket.serialize.ISerializer</code>. The default implementation is <code>org.apache.wicket.serialize.java.JavaSerializer</code> and it uses the standard Java serialization mechanism based on classes ObjectOutputStream and ObjectInputStream. However on Internet we can find other interesting serialization libraries like Kryo1 which performs faster then the standard implementation
 .The serializer in use can be customized with the setSerializer(ISerializer) method defined by setting interface <code>org.apache.wicket.settings.IFrameworkSettings</code>.<p class="paragraph"/>We can access this interface inside the method init of the class Application using the getFrameworkSettings() method :<p class="paragraph"/><div class="code"><pre>@Override
+Page page = pageReference.getPage();</pre></div><p class="paragraph"/>To get the related page instance we must use method getPage.<p class="paragraph"/><h3>Turning off page versioning</h3><p class="paragraph"/>If for any reason we need to switch off versioning for a given page, we can call its method setVersioned(false).<p class="paragraph"/><h3>Pluggable serialization</h3><p class="paragraph"/>Starting from version 1.5 it is possible to choose which implementation of Java serialization will be used by Wicket to store page versions. Wicket serializes pages using an implementation of interface <code>org.apache.wicket.serialize.ISerializer</code>. The default implementation is <code>org.apache.wicket.serialize.java.JavaSerializer</code> and it uses the standard Java serialization mechanism based on classes ObjectOutputStream and ObjectInputStream. However on Internet we can find other interesting serialization libraries like <a href="https://github.com/EsotericSoftware/kryo" target="b
 lank">Kryo</a> or <a href="http://ruedigermoeller.github.io/fast-serialization/" target="blank">Fast</a> which perform faster then the standard implementation. The serializer in use can be customized with the setSerializer(ISerializer) method defined by setting interface <code>org.apache.wicket.settings.IFrameworkSettings</code>.<p class="paragraph"/>We can access this interface inside the method init of the class Application using the getFrameworkSettings() method :<p class="paragraph"/><div class="code"><pre>@Override
 <span class="java&#45;keyword">public</span> void init()
 &#123;
 	<span class="java&#45;keyword">super</span>.init();
 	getFrameworkSettings().setSerializer(yourSerializer);
-&#125;</pre></div><p class="paragraph"/>A serializer based on Kryo library is provided by the WicketStuff project. You can find more information on this project, as well as the instructions to use its modules, in Appendix B.<p class="paragraph"/><h3>Page caching</h3><p class="paragraph"/>By default Wicket persists versions of pages into a session-relative file on disk, but it uses a two-levels cache to speed up this process. The first level of the cache uses a http session attribute called “wicket:persistentPageManagerData-&#60;APPLICATION_NAME&#62;” to store pages. The second level cache stores pages into application-scoped variables which are identified by a session id and a page id.<p class="paragraph"/>The following picture is an overview of these two caching levels:<p class="paragraph"/><img border="0" class="center" src="../img/wicket-cache.png"></img><p class="paragraph"/>The session-scoped cache is faster then the other memory levels but it contains only the pages 
 used to serve the last request. Wicket allows us to set the maximum amount of memory allowed for the application-scoped cache and for the page store file. Both parameters can be configured via setting interface <code>org.apache.wicket.settings.IStoreSettings</code>.<p class="paragraph"/>This interface provides the setMaxSizePerSession(Bytes bytes) method to set the size for page store file. The Bytes parameter is the maximum size allowed for this file:<p class="paragraph"/><div class="code"><pre>@Override
+&#125;</pre></div><p class="paragraph"/>A serializer based on Kryo library and another one based on Fast are provided by the WicketStuff project. You can find more information on this project, as well as the instructions to use its modules, in Appendix B.<p class="paragraph"/><h3>Page caching</h3><p class="paragraph"/>By default Wicket persists versions of pages into a session-relative file on disk, but it uses a two-levels cache to speed up this process. The first level of the cache uses a http session attribute called “wicket:persistentPageManagerData-&#60;APPLICATION_NAME&#62;” to store pages. The second level cache stores pages into application-scoped variables which are identified by a session id and a page id.<p class="paragraph"/>The following picture is an overview of these two caching levels:<p class="paragraph"/><img border="0" class="center" src="../img/wicket-cache.png"></img><p class="paragraph"/>The session-scoped cache is faster then the other memory levels 
 but it contains only the pages used to serve the last request. Wicket allows us to set the maximum amount of memory allowed for the application-scoped cache and for the page store file. Both parameters can be configured via setting interface <code>org.apache.wicket.settings.IStoreSettings</code>.<p class="paragraph"/>This interface provides the setMaxSizePerSession(Bytes bytes) method to set the size for page store file. The Bytes parameter is the maximum size allowed for this file:<p class="paragraph"/><div class="code"><pre>@Override
 <span class="java&#45;keyword">public</span> void init()
 &#123;
 	<span class="java&#45;keyword">super</span>.init();
@@ -293,7 +293,7 @@ Page '&#60;page class&#62;' is not state
 <div id="footer">
     
 Copyright &copy; 2013-2014 — <a href="http://www.apache.org/" target="_blank">The Apache Software Foundation</a> 
-                      — <b style="color:#E8590A !important;">(Generated on: 2014-11-11)</b>
+                      — <b style="color:#E8590A !important;">(Generated on: 2015-02-03)</b>
 
     
 </div>

Modified: wicket/common/site/trunk/_site/guide/guide/whyLearn.html
URL: http://svn.apache.org/viewvc/wicket/common/site/trunk/_site/guide/guide/whyLearn.html?rev=1656683&r1=1656682&r2=1656683&view=diff
==============================================================================
--- wicket/common/site/trunk/_site/guide/guide/whyLearn.html (original)
+++ wicket/common/site/trunk/_site/guide/guide/whyLearn.html Tue Feb  3 11:19:18 2015
@@ -247,7 +247,7 @@ Wicket is not the only component oriente
 <div id="footer">
     
 Copyright &copy; 2013-2014 — <a href="http://www.apache.org/" target="_blank">The Apache Software Foundation</a> 
-                      — <b style="color:#E8590A !important;">(Generated on: 2014-11-11)</b>
+                      — <b style="color:#E8590A !important;">(Generated on: 2015-02-03)</b>
 
     
 </div>

Modified: wicket/common/site/trunk/_site/guide/guide/wicketstuff.html
URL: http://svn.apache.org/viewvc/wicket/common/site/trunk/_site/guide/guide/wicketstuff.html?rev=1656683&r1=1656682&r2=1656683&view=diff
==============================================================================
--- wicket/common/site/trunk/_site/guide/guide/wicketstuff.html (original)
+++ wicket/common/site/trunk/_site/guide/guide/wicketstuff.html Tue Feb  3 11:19:18 2015
@@ -180,6 +180,9 @@ function addJsClass() {
                     <div class="toc-item" style="margin-left:0px"><a href="#wicketstuff_6"><strong>27.6</strong><span>Module wicketstuff-rest-annotations</span></a>
                     </div>
                     
+                    <div class="toc-item" style="margin-left:0px"><a href="#wicketstuff_7"><strong>27.7</strong><span>Module stateless</span></a>
+                    </div>
+                    
                 </div>
                 
 
@@ -298,6 +301,12 @@ To write/read objects to response/from r
 
 
 
+<h2 id="wicketstuff_7">27.7 Module stateless</h2>
+Wicket makes working with AJAX easy and pleasant with its component-oriented abstraction. However as side effect, AJAX components and behaviors make their hosting page stateful. This can be quite annoying if we are working on a page that must be stateless (for example a login page). 
+In this case an obvious solution would be to roll out our own stateless components/behaviors, but Wicketstuff alredy offers such kind of artifacts with <code>stateless</code> module. Here you can find the stateless version of the basic AJAX componets and behaviors shiped with Wicket, like <code>StatelessAjaxSubmitLink</code>, <code>StatelessAjaxFallbackLink</code>, <code>StatelessAjaxEventBehavior</code>, <code>StatelessAjaxFormSubmitBehavior</code> etc&#8230;
+A short introduction to this module can be found on its <a href="https://github.com/wicketstuff/core/tree/master/jdk-1.7-parent/stateless-parent" target="blank">home page</a> .<p class="paragraph"/>
+
+
                 <div style="clear:both;margin-top:15px;"></div>
                 
                     <div class="toc-item prev-left"><a href="../guide/maven.html">&lt;&lt; <strong>26</strong><span>Working with Maven (Appendix)</span></a></div>
@@ -324,7 +333,7 @@ To write/read objects to response/from r
 <div id="footer">
     
 Copyright &copy; 2013-2014 — <a href="http://www.apache.org/" target="_blank">The Apache Software Foundation</a> 
-                      — <b style="color:#E8590A !important;">(Generated on: 2014-11-11)</b>
+                      — <b style="color:#E8590A !important;">(Generated on: 2015-02-03)</b>
 
     
 </div>

Modified: wicket/common/site/trunk/_site/guide/index.html
URL: http://svn.apache.org/viewvc/wicket/common/site/trunk/_site/guide/index.html?rev=1656683&r1=1656682&r2=1656683&view=diff
==============================================================================
--- wicket/common/site/trunk/_site/guide/index.html (original)
+++ wicket/common/site/trunk/_site/guide/index.html Tue Feb  3 11:19:18 2015
@@ -492,6 +492,8 @@ function addJsClass(el) {
                             
                             <div class="toc-item" style="margin-left:10px"><a href="./guide/wicketstuff.html#wicketstuff_6"><strong>27.6</strong><span>Module wicketstuff-rest-annotations</span></a></div>
                             
+                            <div class="toc-item" style="margin-left:10px"><a href="./guide/wicketstuff.html#wicketstuff_7"><strong>27.7</strong><span>Module stateless</span></a></div>
+                            
                             <div class="toc-item" style="margin-left:0px"><a href="./guide/redirects.html"><strong>28</strong><span>Lost In Redirection With Apache Wicket (Appendix)</span></a></div>
                             
                             <div class="toc-item" style="margin-left:0px"><a href="./guide/contributing.html"><strong>29</strong><span>Contributing to this guide (Appendix)</span></a></div>
@@ -519,7 +521,7 @@ function addJsClass(el) {
         <div id="footer">
             
 Copyright &copy; 2013-2014 — <a href="http://www.apache.org/" target="_blank">The Apache Software Foundation</a> 
-                      — <b style="color:#E8590A !important;">(Generated on: 2014-11-15)</b>
+                      — <b style="color:#E8590A !important;">(Generated on: 2015-02-03)</b>
 
             
         </div>