Author: rgielen Date: Mon Feb 29 19:38:05 2016 New Revision: 981415 Log: update volunteers and docs
Added: websites/production/struts/content/docs/ajax-validation.data/struts2-ajax-vali-flow.png (with props) websites/production/struts/content/docs/s2-027.html websites/production/struts/content/docs/tiles-plugin.html Modified: websites/production/struts/content/docs/action-configuration.html websites/production/struts/content/docs/actionmapper.html websites/production/struts/content/docs/ajax-and-javascript-recipes.html websites/production/struts/content/docs/ajax-validation.html websites/production/struts/content/docs/ajax.html websites/production/struts/content/docs/annotations.html websites/production/struts/content/docs/building-struts-2-fast-track-release.html websites/production/struts/content/docs/building-struts-2-normal-release.html websites/production/struts/content/docs/building-struts-annotations.html websites/production/struts/content/docs/building-struts-master.html websites/production/struts/content/docs/cdi-plugin.html websites/production/struts/content/docs/configuration-provider-configuration.html websites/production/struts/content/docs/control-tags.html websites/production/struts/content/docs/convention-plugin.html websites/production/struts/content/docs/create-struts-2-web-application-with-artifacts-in-web-inf-lib-and-use-ant-to-build-the-application.html websites/production/struts/content/docs/crud-demo-i.html websites/production/struts/content/docs/cssxhtml-form-template.html websites/production/struts/content/docs/faqs.html websites/production/struts/content/docs/file-upload.html websites/production/struts/content/docs/form-tags.html websites/production/struts/content/docs/freemarker.html websites/production/struts/content/docs/guides.html websites/production/struts/content/docs/how-to-build-the-portlet-war-for-a-specific-portal-server.html websites/production/struts/content/docs/interceptors.html websites/production/struts/content/docs/json-plugin.html websites/production/struts/content/docs/localization.html websites/production/struts/content/docs/message-store-interceptor.html websites/production/struts/content/docs/objectfactory.html websites/production/struts/content/docs/obtain-response.html websites/production/struts/content/docs/ognl-basics.html websites/production/struts/content/docs/one-time-steps.html websites/production/struts/content/docs/plugin-developers-guide.html websites/production/struts/content/docs/portlet-tiles-plugin.html websites/production/struts/content/docs/processing-forms.html websites/production/struts/content/docs/release-notes-202.html websites/production/struts/content/docs/release-plan-200.html websites/production/struts/content/docs/rest-plugin.html websites/production/struts/content/docs/result-configuration.html websites/production/struts/content/docs/result-types.html websites/production/struts/content/docs/s2-003.html websites/production/struts/content/docs/sample-announcements.html websites/production/struts/content/docs/security-bulletins.html websites/production/struts/content/docs/security.html websites/production/struts/content/docs/struts-2-blank-archetype.html websites/production/struts/content/docs/struts-2-maven-archetypes.html websites/production/struts/content/docs/struts-2-spring-2-jpa-ajax.html websites/production/struts/content/docs/struts-next.html websites/production/struts/content/docs/tiles-3-plugin.html websites/production/struts/content/docs/tiles-use.html websites/production/struts/content/docs/tutoriallesson06.html websites/production/struts/content/docs/type-conversion.html websites/production/struts/content/docs/user-guide.html websites/production/struts/content/docs/using-freemarker-templates.html websites/production/struts/content/docs/validation.html websites/production/struts/content/docs/webxml.html websites/production/struts/content/docs/what-are-some-of-the-frameworks-best-features.html websites/production/struts/content/docs/what-is-the-actioncontext.html websites/production/struts/content/index.html websites/production/struts/content/volunteers.html Modified: websites/production/struts/content/docs/action-configuration.html ============================================================================== --- websites/production/struts/content/docs/action-configuration.html (original) +++ websites/production/struts/content/docs/action-configuration.html Mon Feb 29 19:38:05 2016 @@ -139,11 +139,11 @@ under the License. <div class="pagecontent"> <div class="wiki-content"> <div id="ConfluenceContent"><p>The action mappings are the basic "unit-of-work" in the framework. Essentially, the action maps an identifier to a handler class. When a request matches the action's name, the framework uses the mapping to determine how to process the request.</p><p><style type="text/css">/*<![CDATA[*/ -div.rbtoc1453884195503 {padding: 0px;} -div.rbtoc1453884195503 ul {list-style: disc;margin-left: 0px;} -div.rbtoc1453884195503 li {margin-left: 0px;padding-left: 0px;} +div.rbtoc1456773354482 {padding: 0px;} +div.rbtoc1456773354482 ul {list-style: disc;margin-left: 0px;} +div.rbtoc1456773354482 li {margin-left: 0px;padding-left: 0px;} -/*]]>*/</style></p><div class="toc-macro rbtoc1453884195503"> +/*]]>*/</style></p><div class="toc-macro rbtoc1456773354482"> <ul class="toc-indentation"><li><a shape="rect" href="#ActionConfiguration-ActionMappings">Action Mappings</a></li><li><a shape="rect" href="#ActionConfiguration-ActionNames">Action Names</a></li><li><a shape="rect" href="#ActionConfiguration-ActionMethods">Action Methods</a></li><li><a shape="rect" href="#ActionConfiguration-WildcardMethod">Wildcard Method</a></li><li><a shape="rect" href="#ActionConfiguration-DynamicMethodInvocation">Dynamic Method Invocation</a> <ul class="toc-indentation"><li><a shape="rect" href="#ActionConfiguration-StrictDMI">Strict DMI</a></li><li><a shape="rect" href="#ActionConfiguration-StrictMethodInvocation">Strict Method Invocation</a></li></ul> </li><li><a shape="rect" href="#ActionConfiguration-ActionSupportDefault">ActionSupport Default</a></li><li><a shape="rect" href="#ActionConfiguration-Post-BackDefault">Post-Back Default</a></li><li><a shape="rect" href="#ActionConfiguration-ActionDefault">Action Default</a> Modified: websites/production/struts/content/docs/actionmapper.html ============================================================================== --- websites/production/struts/content/docs/actionmapper.html (original) +++ websites/production/struts/content/docs/actionmapper.html Mon Feb 29 19:38:05 2016 @@ -139,11 +139,11 @@ under the License. <div class="pagecontent"> <div class="wiki-content"> <div id="ConfluenceContent"><p><style type="text/css">/*<![CDATA[*/ -div.rbtoc1453884194236 {padding: 0px;} -div.rbtoc1453884194236 ul {list-style: disc;margin-left: 0px;} -div.rbtoc1453884194236 li {margin-left: 0px;padding-left: 0px;} +div.rbtoc1456773364672 {padding: 0px;} +div.rbtoc1456773364672 ul {list-style: disc;margin-left: 0px;} +div.rbtoc1456773364672 li {margin-left: 0px;padding-left: 0px;} -/*]]>*/</style></p><div class="toc-macro rbtoc1453884194236"> +/*]]>*/</style></p><div class="toc-macro rbtoc1456773364672"> <ul class="toc-indentation"><li><a shape="rect" href="#ActionMapper-Description">Description</a></li><li><a shape="rect" href="#ActionMapper-DefaultActionMapper">DefaultActionMapper</a> <ul class="toc-indentation"><li><a shape="rect" href="#ActionMapper-Methodprefix">Method prefix</a></li><li><a shape="rect" href="#ActionMapper-Actionprefix">Action prefix</a></li></ul> </li><li><a shape="rect" href="#ActionMapper-CustomActionMapper">Custom ActionMapper</a></li><li><a shape="rect" href="#ActionMapper-CompositeActionMapper">CompositeActionMapper</a></li><li><a shape="rect" href="#ActionMapper-PrefixBasedActionMapper">PrefixBasedActionMapper</a></li><li><a shape="rect" href="#ActionMapper-ActionMapperandActionMappingobjects">ActionMapper and ActionMapping objects</a> @@ -221,7 +221,7 @@ with something else in struts.xml) will <pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;"><bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="mymapper" class="com.mycompany.myapp.MyActionMapper" /> <constant name="struts.mapper.class" value="mymapper" /> </pre> -</div></div><p>Possible uses of the ActionMapper include defining your own, cleaner namespaces, such as URLs like <strong>/person/1</strong>, which would be similar to a request to <strong>/getPerson.action?personID=1</strong> using the DefaultActionMapper.</p><h2 id="ActionMapper-CompositeActionMapper">CompositeActionMapper</h2><p>A composite action mapper that is capable of delegating to a series of <a shape="rect" href="actionmapper.html">ActionMapper</a> if the former failed to obtained a valid <a shape="rect" class="createlink" href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&title=ActionMapping&linkCreation=true&fromPageId=14128">ActionMapping</a> or uri.</p><p>It is configured through <a shape="rect" href="strutsxml.html">struts.xml</a>. For example, with the following entries in struts.xml</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> +</div></div><p>Possible uses of the ActionMapper include defining your own, cleaner namespaces, such as URLs like <strong>/person/1</strong>, which would be similar to a request to <strong>/getPerson.action?personID=1</strong> using the DefaultActionMapper.</p><h2 id="ActionMapper-CompositeActionMapper">CompositeActionMapper</h2><p>A composite action mapper that is capable of delegating to a series of <a shape="rect" href="actionmapper.html">ActionMapper</a> if the former failed to obtained a valid <a shape="rect" class="unresolved" href="#">ActionMapping</a> or uri.</p><p>It is configured through <a shape="rect" href="strutsxml.html">struts.xml</a>. For example, with the following entries in struts.xml</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> <pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;"><constant name="struts.mapper.class" value="composite" /> <constant name="struts.mapper.composite" value="struts,restful,restful2" /> </pre> Modified: websites/production/struts/content/docs/ajax-and-javascript-recipes.html ============================================================================== --- websites/production/struts/content/docs/ajax-and-javascript-recipes.html (original) +++ websites/production/struts/content/docs/ajax-and-javascript-recipes.html Mon Feb 29 19:38:05 2016 @@ -142,11 +142,11 @@ under the License. <p>The Dojo plugin will be deprecated on Struts 2.1</p></div></div> <style type="text/css">/*<![CDATA[*/ -div.rbtoc1453884465157 {padding: 0px;} -div.rbtoc1453884465157 ul {list-style: none;margin-left: 0px;padding-left: 20px;} -div.rbtoc1453884465157 li {margin-left: 0px;padding-left: 0px;} +div.rbtoc1456773636859 {padding: 0px;} +div.rbtoc1456773636859 ul {list-style: none;margin-left: 0px;padding-left: 20px;} +div.rbtoc1456773636859 li {margin-left: 0px;padding-left: 0px;} -/*]]>*/</style><div class="toc-macro rbtoc1453884465157"> +/*]]>*/</style><div class="toc-macro rbtoc1456773636859"> <ul class="toc-indentation"><li><a shape="rect" href="#AjaxandJavaScriptRecipes-Common">Common</a></li><li><a shape="rect" href="#AjaxandJavaScriptRecipes-Requests">Requests</a> <ul class="toc-indentation"><li><a shape="rect" href="#AjaxandJavaScriptRecipes-Requestistriggeredbyatopic">Request is triggered by a topic</a></li><li><a shape="rect" href="#AjaxandJavaScriptRecipes-Attachedtoanevent">Attached to an event</a></li><li><a shape="rect" href="#AjaxandJavaScriptRecipes-Attachedtoaneventonmultiplesources">Attached to an event on multiple sources</a></li><li><a shape="rect" href="#AjaxandJavaScriptRecipes-Attachedtomultipleeventsonmultiplesources">Attached to multiple events on multiple sources</a></li><li><a shape="rect" href="#AjaxandJavaScriptRecipes-Updatetargetelementwithcontentreturnedfromurl">Update target element with content returned from url</a></li><li><a shape="rect" href="#AjaxandJavaScriptRecipes-Updatemultipletargetelementswithcontentreturnedfromurl">Update multiple target elements with content returned from url</a></li><li><a shape="rect" href="#AjaxandJavaScriptRecipes-Showindicatorwhilerequestisinprogress">Show indicator while request is in progress</a></li><li><a shape="rect" href="#AjaxandJavaScriptRecipes-Highlightcontentoftargetwithbluecolor,for2seconds">Highlight content of target with blue color, for 2 seconds</a></li><li><a shape="rect" href="#AjaxandJavaScriptRecipes-ExecuteJavaScriptinthereturnedcontent">Execute JavaScript in the returned content</a></li><li><a shape="rect" href="#AjaxandJavaScriptRecipes-Publishatopicbeforetherequest">Publish a topic before the request</a></li><li><a shape="rect" href="#AjaxandJavaScriptRecipes-Publishatopicaftertherequest">Publish a topic after the request</a></li><li><a shape="rect" href="#AjaxandJavaScriptRecipes-Publishatopiconerror">Publish a topic on error</a></li><li><a shape="rect" href="#AjaxandJavaScriptRecipes-Showafixederrormessageonerror">Show a fixed error message on error</a></li><li><a shape="rect" href="#AjaxandJavaScriptRecipes-Preventarequest">Prevent a request</a></li><li><a shape="rect" href="#AjaxandJavaScriptRecipes-Submitaform(plainform)">Submit a form (plain form)</a></li><li><a shape="rect" href="#AjaxandJavaScriptRecipes-Submitaform(usings:formtag)">Submit a form (using s:form tag)</a></li></ul> </li><li><a shape="rect" href="#AjaxandJavaScriptRecipes-Div">Div</a> Added: websites/production/struts/content/docs/ajax-validation.data/struts2-ajax-vali-flow.png ============================================================================== Binary file - no diff available. Propchange: websites/production/struts/content/docs/ajax-validation.data/struts2-ajax-vali-flow.png ------------------------------------------------------------------------------ svn:mime-type = image/png Modified: websites/production/struts/content/docs/ajax-validation.html ============================================================================== --- websites/production/struts/content/docs/ajax-validation.html (original) +++ websites/production/struts/content/docs/ajax-validation.html Mon Feb 29 19:38:05 2016 @@ -138,143 +138,356 @@ under the License. <div class="pagecontent"> <div class="wiki-content"> - <div id="ConfluenceContent"><div class="confluence-information-macro confluence-information-macro-warning"><span class="aui-icon aui-icon-small aui-iconfont-error confluence-information-macro-icon"></span><div class="confluence-information-macro-body"> -<p>2.0.x releases of Struts 2 use DWR for AJAX validation. This documentation refers to version <strong>2.1</strong>.</p></div></div> - -<h2 id="AJAXValidation-Description">Description</h2> - -<p>Struts provides <a shape="rect" href="client-validation.html">client side validation</a>(using JavaScript) for a few validators. Using AJAX validation, all <a shape="rect" href="validation.html">validators</a> available to the application on the server side can be used without forcing the page to reload, just to show validation errors. AJAX validation has a server side, which is in included the Struts core jar (an interceptor and some utility JavaScript files), and a client side, which is included in the Dojo plugin.</p> - -<div class="confluence-information-macro confluence-information-macro-note"><span class="aui-icon aui-icon-small aui-iconfont-warning confluence-information-macro-icon"></span><div class="confluence-information-macro-body"> -<p>To use AJAX validation out of the box, install the Dojo plugin. An example is provided on how to use AJAX validation with Prototype, in this case the Dojo plugin is not required.</p></div></div> - -<h2 id="AJAXValidation-Outofthebox">Out of the box</h2> - -<h3 id="AJAXValidation-Createtheactionclass">Create the action class</h3> -<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> -<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[ - -public class QuizAction extends ActionSupport { - - private static final long serialVersionUID = -7505437345373234225L; - - String name; - int age; - String answer; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getAge() { - return age; - } - - public void setAge(int age) { - this.age = age; - } - - public String getAnswer() { - return answer; - } - - public void setAnswer(String answer) { - this.answer = answer; - } -} - -]]></script> -</div></div> - -<h3 id="AJAXValidation-Createthevalidation.xml">Create the validation.xml</h3> -<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> -<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;"> -<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"> -<validators> - <field name="name"> - <field-validator type="requiredstring"> - <message>You must enter a name</message> - </field-validator> - </field> - <field name="age"> - <field-validator type="int"> - <param name="min">13</param> - <param name="max">19</param> - <message>Only people ages 13 to 19 may take this quiz</message> - </field-validator> - </field> -</validators> -</pre> -</div></div> - -<h3 id="AJAXValidation-MaptheAction">Map the Action</h3> -<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> -<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;"> -<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> + <div id="ConfluenceContent"><h2 id="AJAXValidation-Description">Description</h2><p>Struts provides <a shape="rect" href="client-validation.html">client side validation</a>(using JavaScript) for a few validators. Using AJAX validation, all <a shape="rect" href="validation.html">validators</a> available to the application on the server side can be used without forcing the page to reload, just to show validation errors. AJAX validation has a server side, which is in included in <a shape="rect" href="https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=34268">JSON Plugin</a> (an interceptor and a result). Client side must be handled by applictions themself. One reason for that is there are too many JavaScript frameworks and libraries. Struts has no preference which of them you use. Previous versions of Struts included a client side which was relying on the Dojo JS framework and was located in Struts Dojo plugin. That has been deprecated for a long time and was ev entually removed.</p><h2 id="AJAXValidation-Example">Example</h2><p>This example is taken from the Struts showcase application.</p><h3 id="AJAXValidation-Createtheactionclass">Create the action class</h3><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> +<pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">public class AjaxFormSubmitAction extends ActionSupport { + private String requiredValidatorField = null; + private String requiredStringValidatorField = null; + private Integer integerValidatorField = null; + private Date dateValidatorField = null; + private String emailValidatorField = null; + private String urlValidatorField = null; + private String stringLengthValidatorField = null; + private String regexValidatorField = null; + private String fieldExpressionValidatorField = null; + @Override + public void validate() { + if (hasFieldErrors()) { + addActionError("Errors present!"); + } + } + public Date getDateValidatorField() { + return dateValidatorField; + } + @DateRangeFieldValidator( + min="01/01/1990", + max="01/01/2000", + message="must be a min 01-01-1990 max 01-01-2000 if supplied") + public void setDateValidatorField(Date dateValidatorField) { + this.dateValidatorField = dateValidatorField; + } + public String getEmailValidatorField() { + return emailValidatorField; + } + @EmailValidator(message="must be a valid email if supplied") + public void setEmailValidatorField(String emailValidatorField) { + this.emailValidatorField = emailValidatorField; + } + public Integer getIntegerValidatorField() { + return integerValidatorField; + } + @IntRangeFieldValidator(min="1", max="10", message="must be integer min 1 max 10 if supplied") + public void setIntegerValidatorField(Integer integerValidatorField) { + this.integerValidatorField = integerValidatorField; + } + public String getRegexValidatorField() { + return regexValidatorField; + } + @RegexFieldValidator( + regex="[^<>]+", + message="regexValidatorField must match a regexp (.*\\.txt) if specified") + public void setRegexValidatorField(String regexValidatorField) { + this.regexValidatorField = regexValidatorField; + } + public String getRequiredStringValidatorField() { + return requiredStringValidatorField; + } + @RequiredStringValidator(trim=true, message="required and must be string") + public void setRequiredStringValidatorField(String requiredStringValidatorField) { + this.requiredStringValidatorField = requiredStringValidatorField; + } + public String getRequiredValidatorField() { + return requiredValidatorField; + } + @RequiredFieldValidator(message="required") + public void setRequiredValidatorField(String requiredValidatorField) { + this.requiredValidatorField = requiredValidatorField; + } + public String getStringLengthValidatorField() { + return stringLengthValidatorField; + } + @StringLengthFieldValidator( + minLength="2", + maxLength="4", + trim=true, + message="must be a String of a specific greater than 1 less than 5 if specified") + public void setStringLengthValidatorField(String stringLengthValidatorField) { + this.stringLengthValidatorField = stringLengthValidatorField; + } + public String getFieldExpressionValidatorField() { + return fieldExpressionValidatorField; + } + @FieldExpressionValidator( + expression = "(fieldExpressionValidatorField == requiredValidatorField)", + message = "must be the same as the Required Validator Field if specified") + public void setFieldExpressionValidatorField( + String fieldExpressionValidatorField) { + this.fieldExpressionValidatorField = fieldExpressionValidatorField; + } + public String getUrlValidatorField() { + return urlValidatorField; + } + @UrlValidator(message="must be a valid url if supplied") + public void setUrlValidatorField(String urlValidatorField) { + this.urlValidatorField = urlValidatorField; + } +}</pre> +</div></div><p> </p><h3 id="AJAXValidation-MaptheAction">Map the Action</h3><p>Note that is is not necessary when using <a shape="rect" href="https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=73711">Convention Plugin</a>.</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> +<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;"><!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package> - <action name="quizAjax" class="org.apache.struts2.showcase.validation.QuizAction"> + <action name="ajaxFormSubmit" class="org.apache.struts2.showcase.validation.AjaxFormSubmitAction"> <interceptor-ref name="jsonValidationWorkflowStack"/> - <result name="input">quiz-ajax.jsp</result> - <result>quiz-success.jsp</result> + <result name="input">/WEB-INF/validation/ajaxFormSubmit.jsp</result> + <result type="jsonActionRedirect">ajaxFormSubmitSuccess</result> </action> </package> </pre> -</div></div> - -<p>AJAX validation is performed by the <em>jsonValidation</em> interceptor. This interceptor is included in the <em>jsonValidationWorkflowStack</em>, and is required in order to perform AJAX validation. Normal results(input, success, etc) should be provided for the action in the case that someone tries to access the action directly, in which case normal validation will be triggered. So, how does the <em>jsonValidation</em> know that it must perform AJAX validation vs regular validation? We will see that in a minute, but you don't need to know that in order to use AJAX validation.</p> - -<h3 id="AJAXValidation-CreatetheJSP">Create the JSP </h3> -<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> -<pre class="brush: html; gutter: false; theme: Default" style="font-size:12px;"> -<%@ taglib prefix="s" uri="/struts-tags" %> -<%@ taglib prefix="sx" uri="/struts-dojo-tags" %> - +</div></div><p>AJAX validation is performed by the <em>jsonValidation</em> interceptor. This interceptor is included in the <em>jsonValidationWorkflowStack</em>, and is required in order to perform AJAX validation. Normal results(input, success, etc) should be provided for the action in the case that someone tries to access the action directly, in which case normal validation will be triggered. So, how does the <em>jsonValidation</em> know that it must perform AJAX validation vs regular validation? We will see that in a minute, but you don't need to know that in order to use AJAX validation. Same applies for specialized Redirect Result Type <em>jsonActionRedirect</em>.</p><h3 id="AJAXValidation-CreatetheJSP">Create the JSP</h3><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> +<pre class="brush: html; gutter: false; theme: Default" style="font-size:12px;"><%@taglib prefix="s" uri="/struts-tags" %> <html> <head> - <title>Validation - AJAX</title> - <sx:head /> + <title>Struts2 Showcase - Validation - AJAX Form Submit</title> + <s:head theme="xhtml"/> </head> - -<s:url id="url" namespace="/validation" action="quizAjax"/> - <body> -<s:form method="post" theme="xhtml" namespace="/nodecorate" action="quizAjax" id="form"> - <s:textfield label="Name" name="name" /> - <s:textfield label="Age" name="age" /> - <s:textfield label="Favorite color" name="answer"/> - <sx:submit validate="true" /> -</s:form> -</pre> -</div></div> - -<p>Things to note on this JSP:</p> -<ul><li><sx:head /> must be in the page, to be able to use AJAX functionality.</li><li>The <em>form</em> tag <strong>does not</strong> have <em>validate</em> set to <em>true</em>, which would perform client validation before the AJAX validation.</li><li>The <em>submit</em> tag <strong>must</strong> have <em>validate</em> set to <em>true</em> in order to perform AJAX validation.</li></ul> - - -<p>If validation succeeds, the form will be submitted to the action (where it will be validated again, this time using regular validation). If you want to make this request(the request after validation succeeded) using AJAX (instead of a regular submit), then set the <em>ajaxAfterValidation</em> attribute to <em>true</em> in the submit tag.</p> +<div class="page-header"> + <h1>AJAX Form Submit</h1> +</div> + <h3>Action Errors Will Appear Here</h3> + <s:actionerror theme="ajaxErrorContainers"/> + <hr/> + <s:form method="POST" theme="xhtml"> + <s:textfield label="Required Validator Field" name="requiredValidatorField" theme="ajaxErrorContainers"/> + <s:textfield label="Required String Validator Field" name="requiredStringValidatorField" theme="ajaxErrorContainers"/> + <s:textfield label="Integer Validator Field" name="integerValidatorField" theme="ajaxErrorContainers"/> + <s:textfield label="Date Validator Field" name="dateValidatorField" theme="ajaxErrorContainers"/> + <s:textfield label="Email Validator Field" name="emailValidatorField" theme="ajaxErrorContainers"/> + <s:textfield label="URL Validator Field" name="urlValidatorField" theme="ajaxErrorContainers"/> + <s:textfield label="String Length Validator Field" name="stringLengthValidatorField" theme="ajaxErrorContainers"/> + <s:textfield label="Regex Validator Field" name="regexValidatorField" theme="ajaxErrorContainers"/> + <s:textfield label="Field Expression Validator Field" name="fieldExpressionValidatorField" theme="ajaxErrorContainers"/> + <s:submit label="Submit" cssClass="btn btn-primary"/> + </s:form> +</body> +</html> </pre> +</div></div><p>Things to note on this JSP:</p><ul><li>The <em>form</em> tag <strong>does not</strong> have <em>validate</em> set to <em>true</em>, which would perform client validation before the AJAX validation.</li><li>It uses a customized theme <em>ajaxErrorContainers</em>. The default Struts themes generate HTML-Elements to show validation errors only if errors are present when page is created on server side. But in order to show validation errors that arrive later via AJAX it is necessary to have error-container elements in DOM always.</li></ul><p>What happens if validation succeeds? That depends on your request parameters and action configuration. If you are using <em>jsonActionRedirect</em> result mentioned above the action will be executed while AJAX request is active and respond with JSON providing a new URL to load. Otherwise the AJAX response will be empty and the form must be submitted a 2nd time but as usual request, not AJAX.</p><div class="confluence-information-macro confluence-information-macro-note"><span class="aui-icon aui-icon-small aui-iconfont-warning confluence-information-macro-icon"></span><div class="confluence-information-macro-body"><p>Setting <em>validate</em> to <em>true</em> in the <em>form</em> tag will enable client side, JavaScript validation, which can be used along with AJAX validation (runs before the AJAX validation).</p></div></div><h3 id="AJAXValidation-CustomTheme">Custom Theme</h3><p>In this sample the <a shape="rect" href="struts-2-themes.html">custom theme</a> is based on <em>xhtml</em> theme. It is required to override 3 FTL files.</p><pre>theme.properties</pre><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> +<pre class="brush: text; gutter: false; theme: Default" style="font-size:12px;">parent = xhtml</pre> +</div></div><p> </p><pre>actionerror.ftl</pre><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> +<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;"><#-- + Make sure element is always present. To be filled later via JS. +--> +<ul<#rt/> +<#if parameters.id??> + id="${parameters.id?html}"<#rt/> +</#if> +<#if parameters.cssClass??> + class="${parameters.cssClass?html}"<#rt/> +<#else> + class="errorMessage"<#rt/> +</#if> +<#if parameters.cssStyle??> + style="${parameters.cssStyle?html}"<#rt/> +</#if> +> +<#if (actionErrors?? && actionErrors?size > 0)> + <#list actionErrors as error> + <#if error??> + <li><span><#if parameters.escape>${error!?html}<#else>${error!}</#if></span><#rt/></li><#rt/> + </#if> + </#list> +</#if> +</ul></pre> +</div></div><p> </p><pre>controlfooter.ftl</pre><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> +<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;">${parameters.after!}<#t/> + </td><#lt/> +</tr> +<#if (parameters.errorposition!"top") == 'bottom'> +<#assign hasFieldErrors = parameters.name?? && fieldErrors?? && fieldErrors[parameters.name]??/> +<#if hasFieldErrors> +<tr errorFor="${parameters.id}"> + <td class="tdErrorMessage" colspan="2"><#rt/> + <#if hasFieldErrors> + <#list fieldErrors[parameters.name] as error> + <div class="errorMessage">${error?html}</div><#t/> + </#list> + </#if> + </td><#lt/> +</tr> +</#if> +</#if> -<div class="confluence-information-macro confluence-information-macro-note"><span class="aui-icon aui-icon-small aui-iconfont-warning confluence-information-macro-icon"></span><div class="confluence-information-macro-body"> -<p>Setting <em>validate</em> to <em>true</em> in the <em>form</em> tag will enable client side, JavaScript validation, which can be used along with AJAX validation (runs before the AJAX validation).</p></div></div> - -<div class="confluence-information-macro confluence-information-macro-note"><span class="aui-icon aui-icon-small aui-iconfont-warning confluence-information-macro-icon"></span><div class="confluence-information-macro-body"> -<p>Setting <em>validate</em> to <em>true</em> in the tag that will submit the form will enable AJAX validation. The tag in this example is <em>submit</em>, but it could be <em>a</em>, or <em>bind</em>.</p></div></div> - -<h2 id="AJAXValidation-Howitworks">How it works</h2> -<p>This interceptor must be placed on a stack, following the <em>validation</em> interceptor. The interceptor itself won't perform any validation, but will check for validation errors on the action being invoked (assuming that the action is ValidationAware).</p> - -<p>If you just want to use AJAX validation, without knowing the implementation details, you can skip this section. </p> - -<p>When the <em>jsonValidation</em> interceptor is invoked, it will look for a parameter named <em>struts.enableJSONValidation</em>, this parameter <strong>must</strong> be set to <em>true</em>, otherwise the interceptor won't do anything. Then the interceptor will look for a parameter named <em>struts.validateOnly</em>, if this parameter exists, is set to <em>true</em>, and there are validation errors (o action errors) they will be serialized into JSON in the form:</p> +</pre> +</div></div><p> </p><pre>controlheader-core.ftl</pre><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> +<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;"> <#-- + Always include elements to show errors. They may be filled later via AJAX. +--> +<#assign hasFieldErrors = parameters.name?? && fieldErrors?? && fieldErrors[parameters.name]??/> +<#if (parameters.errorposition!"top") == 'top'> +<tr errorFor="${parameters.id}"> + <td class="tdErrorMessage" colspan="2" data-error-for-fieldname="${parameters.name}"><#rt/> + <#if hasFieldErrors> + <#list fieldErrors[parameters.name] as error> + <div class="errorMessage">${error?html}</div><#t/> + </#list> + </#if> + </td><#lt/> +</tr> +</#if> +<#if !parameters.labelposition?? && (parameters.form.labelposition)??> +<#assign labelpos = parameters.form.labelposition/> +<#elseif parameters.labelposition??> +<#assign labelpos = parameters.labelposition/> +</#if> +<#-- + if the label position is top, + then give the label it's own row in the table +--> +<tr> +<#if (labelpos!"") == 'top'> + <td class="tdLabelTop" colspan="2"><#rt/> +<#else> + <td class="tdLabel"><#rt/> +</#if> +<#if parameters.label??> + <label <#t/> +<#if parameters.id??> + for="${parameters.id?html}" <#t/> +</#if> +<#if hasFieldErrors> + class="errorLabel"<#t/> +<#else> + class="label"<#t/> +</#if> + ><#t/> +<#if parameters.required!false && parameters.requiredPosition!"right" != 'right'> + <span class="required">*</span><#t/> +</#if> +${parameters.label?html}<#t/> +<#if parameters.required!false && parameters.requiredPosition!"right" == 'right'> + <span class="required">*</span><#t/> +</#if> +${parameters.labelseparator!":"?html}<#t/> +<#include "/${parameters.templateDir}/${parameters.expandTheme}/tooltip.ftl" /> +</label><#t/> +</#if> + </td><#lt/> +<#-- add the extra row --> +<#if (labelpos!"") == 'top'> +</tr> +<tr> +</#if> -<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> -<pre class="brush: javascript; gutter: false; theme: Default" style="font-size:12px;"> -{ +</pre> +</div></div><h3 id="AJAXValidation-CSS">CSS</h3><p>To show users some nice visual feedback while waiting for AJAX response you can use a little CSS. Remember to include the referenced <em>indicator.gif</em>.</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> +<pre class="brush: css; gutter: false; theme: Default" style="font-size:12px;">.ajaxVisualFeedback { + width: 16px; + height: 16px; + background-image: url('../images/indicator.gif'); + background-repeat: no-repeat; + float: right; +}</pre> +</div></div><p> </p><h3 id="AJAXValidation-JavaScript">JavaScript</h3><p>Now this is where the magic happens. Here <em>jQuery</em> is used to register an eventhandler which intercepts form submits. It takes care of hiding validation errors that might be present, submit the form via AJAX and handle JSON responses.</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> +<pre class="brush: js; gutter: false; theme: Default" style="font-size:12px;"> /** + * Validates form per AJAX. To be called as onSubmit handler. + * + * @param event onSubmit event + */ +function ajaxFormValidation(event) { + event.preventDefault(); + _removeValidationErrors(); + var _form = $(event.target); + var _formData = _form.serialize(true); + // prepare visual feedback + // you may want to use other elements here + var originalButton = _form.find('.btn-primary'); + // note: jQuery returns an array-like object + if (originalButton && originalButton.length && originalButton.length > 0) { + originalButton.hide(); + var feedbackElement = $('<div class="ajaxVisualFeedback"></div>').insertAfter(originalButton); + var restoreFunction = function() { + originalButton.show(); + feedbackElement.remove(); + } + } + var options = { + data: 'struts.enableJSONValidation=true&struts.validateOnly=false&' + _formData, + async: true, + processData: false, + type: 'POST', + success: function (response, statusText, xhr) { + if (response.location) { + // no validation errors + // action has been executed and sent a redirect URL wrapped as JSON + // cannot use a normal http-redirect (status-code 3xx) as this would be followed by browsers and would not be available here + // follow JSON-redirect + window.location.href = response.location; + } else { + if (restoreFunction) { + restoreFunction(); + } + _handleValidationResult(_form, response); + } + }, + error: function(xhr, textStatus, errorThrown) { + if (restoreFunction) { + restoreFunction(); + } + // show user an error message + _handleValidationResult(_form, {errors: ['Network or server error!']}) + } + } + // send request, after delay to make sure everybody notices the visual feedback :) + window.setTimeout(function() { + var url = _form[0].action; + jQuery.ajax(url, options); + }, 1000); +} +/** + * Removes validation errors from HTML DOM. + */ +function _removeValidationErrors() { + // action errors + // you might want to use a custom ID here + $('ul.errorMessage li').remove(); + // field errors + $('div.errorMessage').remove(); +} +/** + * Incorporates validation errors in HTML DOM. + * + * @param form Form containing errors. + * @param errors Errors from server. + */ +function _handleValidationResult(form, errors) { + // action errors + if (errors.errors) { + // you might want to use a custom ID here + var errorContainer = $('ul.errorMessage'); + $.each(errors.errors, function(index, errorMsg) { + var li = $('<li><span></span></li>'); + li.text(errorMsg); // use text() for security reasons + errorContainer.append(li); + }); + } + // field errors + if (errors.fieldErrors) { + $.each(errors.fieldErrors, function(fieldName, errorMsg) { + var td = $('td[data-error-for-fieldname="' + fieldName + '"]'); + if (td) { + var div = $('<div class="errorMessage"></div>'); + div.text(errorMsg); // use text() for security reasons + td.append(div); + } + }); + } +} +// register onSubmit handler +$(window).bind('load', function() { + $('form').bind('submit', ajaxFormValidation); +});</pre> +</div></div><p> </p><h2 id="AJAXValidation-Howitworks">How it works</h2><p><em>jsonValidation</em> interceptor must be placed on a stack, following the <em>validation</em> interceptor. The interceptor itself won't perform any validation, but will check for validation errors on the action being invoked (assuming that the action is ValidationAware).</p><p>If you just want to use AJAX validation, without knowing the implementation details, you can skip this section.</p><p>When the <em>jsonValidation</em> interceptor is invoked, it will look for a parameter named <em>struts.enableJSONValidation</em>, this parameter <strong>must</strong> be set to <em>true</em>, otherwise the interceptor won't do anything. Then the interceptor will look for a parameter named <em>struts.validateOnly</em>, if this parameter exists, is set to <em>true</em>, and there are validation errors (o action errors) they will be serialized into JSON in the form:</p><div class="code panel pdl" style="border-width : 1px;"><div class="codeContent panelContent pdl"> +<pre class="brush: javascript; gutter: false; theme: Default" style="font-size:12px;">{ "errors": ["Global Error 1", "Global Error 2"], "fieldErrors": { "field1": ["Field 1 Error 1", "Field 1 Error 2"], @@ -282,122 +495,13 @@ public class QuizAction extends ActionSu } } </pre> -</div></div> - -<p>If the action implements the <em>ModelDrive</em> interface, "model." will be stripped from the field names in the returned JSON. If validation succeeds, an empty JSON string will be returned:</p> - -<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> -<pre class="brush: javascript; gutter: false; theme: Default" style="font-size:12px;"> -{} +</div></div><p>If the action implements the <em>ModelDrive</em> interface, "model." will be stripped from the field names in the returned JSON. If validation succeeds (and <em>struts.validateOnly</em> is true), an empty JSON string will be returned:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> +<pre class="brush: javascript; gutter: false; theme: Default" style="font-size:12px;">{} </pre> -</div></div> - -<div class="confluence-information-macro confluence-information-macro-warning"><span class="aui-icon aui-icon-small aui-iconfont-error confluence-information-macro-icon"></span><div class="confluence-information-macro-body"> -<p>Remember to set struts.enableJSONValidation=true in the request to enable AJAX validation</p></div></div> - -<p>To process this response on the client, the file utils.js distributed with Struts defines an object called <em>StrutsUtils</em> whith the following functions (which will work with the "xhtml" and "css_xhtml" themes):</p> - -<ul><li>getValidationErrors(stringData) : Processes response String and returns a JavaScript object with the validation errors</li><li>clearValidationErrors(formNode) : Removes validation errors from a form</li><li>showValidationErrors(formNode, errorObject) : Shows validation errors on a form, the errorObject parameter is the return value of getValidationErrors</li></ul> - - -<p>The file utils.js will be included on the page by the <em>head</em> on the Dojo plugin, if you are using another library for AJAX validation (see Prototype example below), then you need to include this file:</p> - -<div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>Include utils.js</b></div><div class="codeContent panelContent pdl"> -<pre class="brush: javascript; gutter: false; theme: Default" style="font-size:12px;"> -<script language="JavaScript" src="${pageContext.request.contextPath}/struts/utils.js" type="text/javascript"></script> +</div></div><p>If <em>struts.validateOnly</em> is false the action and result are executed. In this case <em>jsonActionRedirect</em> result is very useful. It creates a JSON response in the form:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> +<pre class="brush: javascript; gutter: false; theme: Default" style="font-size:12px;">{"location": "<url to be loaded next>"} </pre> -</div></div> - -<p>and then the validation file specific to the theme being used:</p> - -<div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>Include validation.js fo the xhtml theme</b></div><div class="codeContent panelContent pdl"> -<pre class="brush: javascript; gutter: false; theme: Default" style="font-size:12px;"> -<script language="JavaScript" src="${pageContext.request.contextPath}/struts/xhtml/validation.js" type="text/javascript"></script> -</pre> -</div></div> - -<p>or</p> - -<div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>Include validation.js for the css_xhtml theme</b></div><div class="codeContent panelContent pdl"> -<pre class="brush: javascript; gutter: false; theme: Default" style="font-size:12px;"> -<script language="JavaScript" src="${pageContext.request.contextPath}/struts/css_xhtml/validation.js" type="text/javascript"></script> -</pre> -</div></div> - - -<div class="confluence-information-macro confluence-information-macro-note"><span class="aui-icon aui-icon-small aui-iconfont-warning confluence-information-macro-icon"></span><div class="confluence-information-macro-body"> -<p>Include utils.js and validation.js(the one for the theme being used), if you are not using the Dojo plugin.</p></div></div> - -<h2 id="AJAXValidation-ExampleusingPrototype">Example using Prototype</h2> -<p>In this example we will rewrite the JSP to use Prototype, instead of the Dojo plugin.</p> - -<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> -<pre class="brush: html; gutter: false; theme: Default" style="font-size:12px;"> -<%@ taglib prefix="s" uri="/struts-tags" %> - -<html> -<head> - <title>Validation - Ajax</title> - <!-- Don't forget these 2 files!! --> - <script language="JavaScript" src="${pageContext.request.contextPath}/struts/utils.js" type="text/javascript"></script> - <script language="JavaScript" src="${pageContext.request.contextPath}/struts/xhtml/validation.js" type="text/javascript"></script> - - <!-- Prototype --> - <script src="${pageContext.request.contextPath}/js/prototype.js" type="text/javascript"></script> - <s:head theme="xhtml" /> -</head> - -<s:url id="url" namespace="/validation" action="quizAjax"/> - -<body> - -<s:form method="post" theme="xhtml" namespace="/nodecorate" action="quizAjax" id="form" onsubmit="validate(); return false"> - <s:textfield label="Name" name="name" /> - <s:textfield label="Age" name="age" /> - <s:textfield label="Favorite color" name="answer"/> - <s:submit /> -</s:form> - - -<script type="text/javascript"> - function validate() { - var url = '${url}'; - - new Ajax.Request( - url, - { - method: 'get', - parameters: Form.serialize($('form')) + '&struts.enableJSONValidation=true&struts.validateOnly=true', - onComplete: postValidation - } - ); - } - - function postValidation(request) { - var form = $('form'); - - //clear previous validation errors, if any - StrutsUtils.clearValidationErrors(form); - - //get errors from response - var text = request.responseText; - var errorsObject = StrutsUtils.getValidationErrors(text); - - //show errors, if any - if(errorsObject.fieldErrors) { - StrutsUtils.showValidationErrors(form, errorsObject); - } else { - //good to go, regular submit - form.submit(); - } - } -</script> -</pre> -</div></div> - -<h2 id="AJAXValidation-FlowchartofAJAXvalidation">Flow chart of AJAX validation</h2> - -<p><span class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image" src="ajax-validation.data/ValidationClientAjax.jpg"></span></p></div> +</div></div><div class="confluence-information-macro confluence-information-macro-warning"><span class="aui-icon aui-icon-small aui-iconfont-error confluence-information-macro-icon"></span><div class="confluence-information-macro-body"><p>Remember to set struts.enableJSONValidation=true in the request to enable AJAX validation</p></div></div><p> </p><h2 id="AJAXValidation-FlowchartofAJAXvalidation">Flow chart of AJAX validation</h2><div class="confluence-information-macro confluence-information-macro-note"><span class="aui-icon aui-icon-small aui-iconfont-warning confluence-information-macro-icon"></span><div class="confluence-information-macro-body"><p>Some details are omitted, like results used.</p></div></div><div class="confluence-information-macro confluence-information-macro-note"><span class="aui-icon aui-icon-small aui-iconfont-warning confluence-information-macro-icon"></span><div class="confluence-information-macro-body"><p>As explained above: there is a case where fo rm is submitted twice, one time as AJAX with validation only and another time as usual submit.</p></div></div><p><a shape="rect" href="ajax-validation.data/struts2-ajax-vali-flow.png?version=2&modificationDate=1454052624000&api=v2" data-linked-resource-id="61338002" data-linked-resource-version="2" data-linked-resource-type="attachment" data-linked-resource-default-alias="struts2-ajax-vali-flow.png" data-nice-type="Image" data-linked-resource-content-type="image/png" data-linked-resource-container-id="13850" data-linked-resource-container-version="41"><span class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image" src="ajax-validation.data/struts2-ajax-vali-flow.png"></span></a></p><p> </p></div> </div> Modified: websites/production/struts/content/docs/ajax.html ============================================================================== --- websites/production/struts/content/docs/ajax.html (original) +++ websites/production/struts/content/docs/ajax.html Mon Feb 29 19:38:05 2016 @@ -145,7 +145,7 @@ out.println("Hello World! This is an AJ out.flush(); return null; </pre> -</div></div><p>In Struts 2, we can do the same thing with a Stream result.</p><div class="confluence-information-macro confluence-information-macro-note"><p class="title">There are easier ways!</p><span class="aui-icon aui-icon-small aui-iconfont-warning confluence-information-macro-icon"></span><div class="confluence-information-macro-body"><p>Using a Struts 2 plugin (e.g., JSON plugin, jQuery plugin, etc.) is, in general, preferred to writing the response directly from within an action. See sections following this for further details.</p></div></div><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>Struts 2 Stream result Action</b></div><div class="codeContent panelContent pdl"> +</div></div><p>In Struts 2, we can do the same thing with a Stream result.</p><div class="confluence-information-macro confluence-information-macro-note"><p class="title">There are easier ways!</p><span class="aui-icon aui-icon-small aui-iconfont-warning confluence-information-macro-icon"></span><div class="confluence-information-macro-body"><p>Using a Struts 2 plugin (e.g., <a shape="rect" href="json-plugin.html">JSON plugin</a>, jQuery plugin, etc.) is, in general, preferred to writing the response directly from within an action. See sections following this for further details.</p></div></div><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>Struts 2 Stream result Action</b></div><div class="codeContent panelContent pdl"> <pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">package actions; import java.io.InputStream; Modified: websites/production/struts/content/docs/annotations.html ============================================================================== --- websites/production/struts/content/docs/annotations.html (original) +++ websites/production/struts/content/docs/annotations.html Mon Feb 29 19:38:05 2016 @@ -125,52 +125,7 @@ under the License. <div class="pagecontent"> <div class="wiki-content"> - <div id="ConfluenceContent"><p>In many places, applications can use Java 5 annotations as an alternative to XML and Java properties configuration. This page serves as a reference for all annotations across the framework.</p> - -<h2 id="Annotations-ActionAnnotations">Action Annotations</h2> - -<div class="confluence-information-macro confluence-information-macro-note"><span class="aui-icon aui-icon-small aui-iconfont-warning confluence-information-macro-icon"></span><div class="confluence-information-macro-body"> -<p>Since 2.1, these annotations are provided by the <a shape="rect" href="convention-plugin.html">Convention Plugin</a>. Codebehind and Zero Config plugins are deprecated from 2.1 on.</p></div></div> - -<p>Action annotations are available when the framework scans the classpath for Action classes, rather than specifying individual mappings through XML configuration. See the <a shape="rect" href="convention-plugin.html">Convention Plugin</a> page for information on how to set up classpath scanning to allow the use of Action annotations.</p> - -<div class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> Annotation </p></th><th colspan="1" rowspan="1" class="confluenceTh"><p> Description </p></th></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="convention-plugin.html">Actions Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Group of @Action annotations, maps multiple URLs to the same action </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="convention-plugin.html">Action Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Defines the URL of an action </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="convention-plugin.html">InterceptorRefs Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Gropup of @InterceptorRef annotations </p></td></tr><tr><td colspan="1" rowspan="1" c lass="confluenceTd"><p> <a shape="rect" href="convention-plugin.html">InterceptorRef Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Interceptor, or interceptor stack to be applied to at action </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="convention-plugin.html">Results Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Group of @Result annotations </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="convention-plugin.html">Result Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Defines a result for an action</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="convention-plugin.html">Namespace Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Set the path of the action URL (used to overwrite the default)</p></td></tr><tr><td colspan="1" rowspan="1" cla ss="confluenceTd"><p> <a shape="rect" href="convention-plugin.html">ResultPath Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Set where the results are located (used to overwrite the default)</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="convention-plugin.html">ParentPackage Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Set the parent package of the actions (used to overwrite the default)</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="convention-plugin.html">ExceptionMappings</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Group of @ExceptionMapping annotations</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="convention-plugin.html">ExceptionMapping</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Defines an exception mapping</p></td></tr></tbody></table></div> - - -<h2 id="Annotations-WorkflowAnnotations">Workflow Annotations</h2> - -<div class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> Annotation </p></th><th colspan="1" rowspan="1" class="confluenceTh"><p> Description </p></th></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="inputconfig-annotation.html">InputConfig Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Defines what method to execute, or result to be returned if there are validation errors </p></td></tr></tbody></table></div> - - -<h2 id="Annotations-InterceptorAnnotations">Interceptor Annotations</h2> - -<p>To use these annotations, you have to specify the <a shape="rect" href="annotationworkflowinterceptor.html">AnnotationWorkflowInterceptor</a> to your interceptor stack.</p> -<div class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> Annotation </p></th><th colspan="1" rowspan="1" class="confluenceTh"><p> Description </p></th></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="after-annotation.html">After Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Marks a action method that needs to be executed after the result. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="before-annotation.html">Before Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Marks a action method that needs to be executed before the main action method. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="beforeresult-annotation.html">BeforeResult Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Marks a action method that needs to be executed before the result. </p></td></tr></tbody></table></div> - - -<h2 id="Annotations-ValidationAnnotations">Validation Annotations</h2> - -<p>To use annotation-based validation, annotate the class or interface with <a shape="rect" href="validation-annotation.html">Validation Annotation</a>.</p> - -<div class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> Annotation </p></th><th colspan="1" rowspan="1" class="confluenceTh"><p> Description </p></th></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="conversionerrorfieldvalidator-annotation.html">ConversionErrorFieldValidator Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Checks if there are any conversion errors for a field. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="daterangefieldvalidator-annotation.html">DateRangeFieldValidator Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Checks that a date field has a value within a specified range. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="doublerangefieldvalidator-annotation.html">DoubleRangeFieldValidator Annotation</a> </p></td><td col span="1" rowspan="1" class="confluenceTd"><p> Checks that a double field has a value within a specified range. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="emailvalidator-annotation.html">EmailValidator Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Checks that a field is a valid e-mail address. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="expressionvalidator-annotation.html">ExpressionValidator Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Validates an expression. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="fieldexpressionvalidator-annotation.html">FieldExpressionValidator Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Uses an OGNL expression to perform its validator. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="re ct" href="intrangefieldvalidator-annotation.html">IntRangeFieldValidator Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Checks that a numeric field has a value within a specified range. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="regexfieldvalidator-annotation.html">RegexFieldValidator Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Validates a regular expression for a field. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="requiredfieldvalidator-annotation.html">RequiredFieldValidator Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Checks that a field is non-null. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="requiredstringvalidator-annotation.html">RequiredStringValidator Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Checks th at a String field is not empty. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="stringlengthfieldvalidator-annotation.html">StringLengthFieldValidator Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Checks that a String field is of the right length. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="urlvalidator-annotation.html">UrlValidator Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Checks that a field is a valid URL. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="validation-annotation.html">Validation Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Marker annotation for validation at Type level. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="validations-annotation.html">Validations Annotation</a> </p></td><td colsp an="1" rowspan="1" class="confluenceTd"><p> Used to group validation annotations. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="visitorfieldvalidator-annotation.html">VisitorFieldValidator Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Invokes the validation for a property's object type. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="customvalidator-annotation.html">CustomValidator Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Use this annotation for your custom validator types. </p></td></tr></tbody></table></div> - - -<h3 id="Annotations-Resources">Resources </h3> -<ul><li><a shape="rect" class="external-link" href="http://arsenalist.com/2007/05/10/struts-2-validation-using-annotations/" rel="nofollow">Validation using Annotations</a> (arsenalist)</li></ul> - - -<h2 id="Annotations-TypeConversionAnnotations">Type Conversion Annotations</h2> - -<p>By default, type conversion for Maps and Collections using generics is directly supported.</p> - -<p>In short, instead of specifying the types found in collections and maps as documented in <a shape="rect" href="type-conversion.html">Type Conversion</a>, <strong>the collection's generic type is used</strong>. By using annotations, an application should be able to avoid using any <code>ClassName-conversion.properties</code> files.</p> - -<p>To use annotation-based type conversion, annotate the class or interface with the <a shape="rect" href="conversion-annotation.html">Conversion Annotation</a>.</p> - -<div class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> Annotation </p></th><th colspan="1" rowspan="1" class="confluenceTh"><p> Description </p></th></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="conversion-annotation.html">Conversion Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Marker annotation for type conversions at Type level. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="createifnull-annotation.html">CreateIfNull Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> For Collection and Map types: Create the types within the Collection or Map, if null. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="element-annotation.html">Element Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> For Generic types: Specify t he element type for Collection types and Map values. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="key-annotation.html">Key Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> For Generic types: Specify the key type for Map keys. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="keyproperty-annotation.html">KeyProperty Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> For Generic types: Specify the key property name value. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <a shape="rect" href="typeconversion-annotation.html">TypeConversion Annotation</a> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Used for class and application wide conversion rules. </p></td></tr></tbody></table></div> - - -<h2 id="Annotations-Next:">Next: <a shape="rect" href="configuration-elements.html">Configuration Elements</a></h2></div> + <div id="ConfluenceContent"><p>In many places, applications can use Java 5 annotations as an alternative to XML and Java properties configuration. This page serves as a reference for all annotations across the framework.</p><h2 id="Annotations-ActionAnnotations">Action Annotations</h2><div class="confluence-information-macro confluence-information-macro-note"><span class="aui-icon aui-icon-small aui-iconfont-warning confluence-information-macro-icon"></span><div class="confluence-information-macro-body"><p>Since 2.1, these annotations are provided by the <a shape="rect" href="convention-plugin.html">Convention Plugin</a>. Codebehind and Zero Config plugins are deprecated from 2.1 on.</p></div></div><p>Action annotations are available when the framework scans the classpath for Action classes, rather than specifying individual mappings through XML configuration. See the <a shape="rect" href="convention-plugin.html">Convention Plugin</a> page for information on how to set u p classpath scanning to allow the use of Action annotations.</p><div class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Annotation</p></th><th colspan="1" rowspan="1" class="confluenceTh"><p>Description</p></th></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="convention-plugin.html">Actions Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Group of @Action annotations, maps multiple URLs to the same action</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="convention-plugin.html">Action Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Defines the URL of an action</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="convention-plugin.html">InterceptorRefs Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Gropup of @InterceptorRef annotati ons</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="convention-plugin.html">InterceptorRef Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Interceptor, or interceptor stack to be applied to at action</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="convention-plugin.html">Results Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Group of @Result annotations</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="convention-plugin.html">Result Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Defines a result for an action</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="convention-plugin.html">Namespace Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Set the path of the action URL (used to overwrite the default)</p></td>< /tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="convention-plugin.html">ResultPath Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Set where the results are located (used to overwrite the default)</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="convention-plugin.html">ParentPackage Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Set the parent package of the actions (used to overwrite the default)</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="convention-plugin.html">ExceptionMappings</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Group of @ExceptionMapping annotations</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="convention-plugin.html">ExceptionMapping</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Defines an exception mapping</p>< /td></tr></tbody></table></div><h2 id="Annotations-WorkflowAnnotations">Workflow Annotations</h2><div class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Annotation</p></th><th colspan="1" rowspan="1" class="confluenceTh"><p>Description</p></th></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="inputconfig-annotation.html">InputConfig Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Defines what method to execute, or result to be returned if there are validation errors</p></td></tr></tbody></table></div><h2 id="Annotations-InterceptorAnnotations">Interceptor Annotations</h2><p>To use these annotations, you have to specify the <a shape="rect" href="annotationworkflowinterceptor.html">AnnotationWorkflowInterceptor</a> to your interceptor stack.</p><div class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Anno tation</p></th><th colspan="1" rowspan="1" class="confluenceTh"><p>Description</p></th></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="after-annotation.html">After Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Marks a action method that needs to be executed after the result.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="before-annotation.html">Before Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Marks a action method that needs to be executed before the main action method.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="beforeresult-annotation.html">BeforeResult Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Marks a action method that needs to be executed before the result.</p></td></tr></tbody></table></div><h2 id="Annotations-ValidationAnnotations">Validation Annotations</h2> <p>To use annotation-based validation, annotate the class or interface with <a shape="rect" href="validation-annotation.html">Validation Annotation</a>.</p><div class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Annotation</p></th><th colspan="1" rowspan="1" class="confluenceTh"><p>Description</p></th></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="conversionerrorfieldvalidator-annotation.html">ConversionErrorFieldValidator Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Checks if there are any conversion errors for a field.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="daterangefieldvalidator-annotation.html">DateRangeFieldValidator Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Checks that a date field has a value within a specified range.</p></td></tr><tr><td colspan="1" rowspan="1" cla ss="confluenceTd"><p><a shape="rect" href="doublerangefieldvalidator-annotation.html">DoubleRangeFieldValidator Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Checks that a double field has a value within a specified range.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="emailvalidator-annotation.html">EmailValidator Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Checks that a field is a valid e-mail address.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="expressionvalidator-annotation.html">ExpressionValidator Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Validates an expression.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="fieldexpressionvalidator-annotation.html">FieldExpressionValidator Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Uses an OGNL expression to perform its validator.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="intrangefieldvalidator-annotation.html">IntRangeFieldValidator Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Checks that a numeric field has a value within a specified range.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="regexfieldvalidator-annotation.html">RegexFieldValidator Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Validates a regular expression for a field.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="requiredfieldvalidator-annotation.html">RequiredFieldValidator Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Checks that a field is non-null.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="requiredstringvalidator-annotation.h tml">RequiredStringValidator Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Checks that a String field is not empty.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="stringlengthfieldvalidator-annotation.html">StringLengthFieldValidator Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Checks that a String field is of the right length.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="urlvalidator-annotation.html">UrlValidator Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Checks that a field is a valid URL.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="validation-annotation.html">Validation Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Marker annotation for validation at Type level.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"> <p><a shape="rect" href="validations-annotation.html">Validations Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Used to group validation annotations.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="visitorfieldvalidator-annotation.html">VisitorFieldValidator Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Invokes the validation for a property's object type.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="customvalidator-annotation.html">CustomValidator Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Use this annotation for your custom validator types.</p></td></tr></tbody></table></div><h3 id="Annotations-Resources">Resources</h3><ul><li><a shape="rect" class="external-link" href="http://arsenalist.com/2007/05/10/struts-2-validation-using-annotations/" rel="nofollow">Validation using Annotations</a> (arsenalist)</li> </ul><h2 id="Annotations-TypeConversionAnnotations">Type Conversion Annotations</h2><p>By default, type conversion for Maps and Collections using generics is directly supported.</p><p>In short, instead of specifying the types found in collections and maps as documented in <a shape="rect" href="type-conversion.html">Type Conversion</a>, <strong>the collection's generic type is used</strong>. By using annotations, an application should be able to avoid using any <code>ClassName-conversion.properties</code> files.</p><p>To use annotation-based type conversion, annotate the class or interface with the <a shape="rect" href="conversion-annotation.html">Conversion Annotation</a>.</p><div class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Annotation</p></th><th colspan="1" rowspan="1" class="confluenceTh"><p>Description</p></th></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="conversion-annotatio n.html">Conversion Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Marker annotation for type conversions at Type level.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="createifnull-annotation.html">CreateIfNull Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>For Collection and Map types: Create the types within the Collection or Map, if null.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="element-annotation.html">Element Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>For Generic types: Specify the element type for Collection types and Map values.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="key-annotation.html">Key Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>For Generic types: Specify the key type for Map keys.</p></td></tr><tr><td colspan= "1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="keyproperty-annotation.html">KeyProperty Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>For Generic types: Specify the key property name value.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" href="typeconversion-annotation.html">TypeConversion Annotation</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Used for class and application wide conversion rules.</p></td></tr></tbody></table></div><h2 id="Annotations-TilesAnnotations">Tiles Annotations</h2><p>The <a shape="rect" href="tiles-plugin.html">Tiles Plugin</a> provides it's own set of Annotations. They can be used to keep <code>tiles.xml</code> short. Instead tiles definitions can be created by annotating actions.</p><div class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" class="confluenceTh">Annotation</th><th colspan="1" rowspan="1" class="confluenceT h">Description</th></tr><tr><td colspan="1" rowspan="1" class="confluenceTd">TilesDefinition</td><td colspan="1" rowspan="1" class="confluenceTd">Represents a <code><definition></code> element in <code>tiles.xml</code></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd">TilesDefinitions</td><td colspan="1" rowspan="1" class="confluenceTd">A list of <code>TilesDefinition</code> Annotations</td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p>TilesPutAttribute</p></td><td colspan="1" rowspan="1" class="confluenceTd">Represents a <code><put-attribute></code> element in <code>tiles.xml</code></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd">TilesPutListAttribute</td><td colspan="1" rowspan="1" class="confluenceTd">Represents a <code><put-list-attribute></code> element in <code>tiles.xml</code></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd">TilesAddAttribute</td><td colspan="1" rowspan="1" class="confluenceTd">Represents a <code><add-attribute></code> element in <code>tiles.xml</code></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd">TilesAddListAttribute</td><td colspan="1" rowspan="1" class="confluenceTd">Represents a <code><add-list-attribute></code> element in <code>tiles.xml</code></td></tr></tbody></table></div><p> </p><h2 id="Annotations-Next:">Next: <a shape="rect" href="configuration-elements.html">Configuration Elements</a></h2></div> </div> <div class="tabletitle"> Modified: websites/production/struts/content/docs/building-struts-2-fast-track-release.html ============================================================================== --- websites/production/struts/content/docs/building-struts-2-fast-track-release.html (original) +++ websites/production/struts/content/docs/building-struts-2-fast-track-release.html Mon Feb 29 19:38:05 2016 @@ -139,11 +139,11 @@ under the License. <div class="pagecontent"> <div class="wiki-content"> <div id="ConfluenceContent"><div class="confluence-information-macro confluence-information-macro-warning"><span class="aui-icon aui-icon-small aui-iconfont-error confluence-information-macro-icon"></span><div class="confluence-information-macro-body"><p>This version is outdated! Work-in-progress!</p></div></div><h1 id="BuildingStruts2-Fasttrackrelease-Content">Content</h1><p><style type="text/css">/*<![CDATA[*/ -div.rbtoc1453884618782 {padding: 0px;} -div.rbtoc1453884618782 ul {list-style: none;margin-left: 0px;} -div.rbtoc1453884618782 li {margin-left: 0px;padding-left: 0px;} +div.rbtoc1456773762675 {padding: 0px;} +div.rbtoc1456773762675 ul {list-style: none;margin-left: 0px;} +div.rbtoc1456773762675 li {margin-left: 0px;padding-left: 0px;} -/*]]>*/</style></p><div class="toc-macro rbtoc1453884618782"> +/*]]>*/</style></p><div class="toc-macro rbtoc1456773762675"> <ul class="toc-indentation"><li><span class="TOCOutline">1</span> <a shape="rect" href="#BuildingStruts2-Fasttrackrelease-BuildingSteps(Struts)">Building Steps (Struts)</a> <ul class="toc-indentation"><li><span class="TOCOutline">1.1</span> <a shape="rect" href="#BuildingStruts2-Fasttrackrelease-Gettingready">Getting ready</a></li><li><span class="TOCOutline">1.2</span> <a shape="rect" href="#BuildingStruts2-Fasttrackrelease-Updateversionofarchetypes">Update version of archetypes</a></li><li><span class="TOCOutline">1.3</span> <a shape="rect" href="#BuildingStruts2-Fasttrackrelease-Applysecuritypatch">Apply security patch</a></li><li><span class="TOCOutline">1.4</span> <a shape="rect" href="#BuildingStruts2-Fasttrackrelease-Preparerelease">Prepare release</a></li><li><span class="TOCOutline">1.5</span> <a shape="rect" href="#BuildingStruts2-Fasttrackrelease-Performtherelease">Perform the release</a></li><li><span class="TOCOutline">1.6</span> <a shape="rect" href="#BuildingStruts2-Fasttrackrelease-Movetheassembliestothe/www/people.apache.org/builds/struts/$VERSIONdir">Move the assemblies to the /www/people.apache.org/builds/struts/$VERSION dir</a></li> <li><span class="TOCOutline">1.7</span> <a shape="rect" href="#BuildingStruts2-Fasttrackrelease-Jirastuff">Jira stuff</a></li><li><span class="TOCOutline">1.8</span> <a shape="rect" href="#BuildingStruts2-Fasttrackrelease-Voteonit">Vote on it</a></li><li><span class="TOCOutline">1.9</span> <a shape="rect" href="#BuildingStruts2-Fasttrackrelease-Copyfiles">Copy files</a></li><li><span class="TOCOutline">1.10</span> <a shape="rect" href="#BuildingStruts2-Fasttrackrelease-Promoterelease">Promote release</a></li><li><span class="TOCOutline">1.11</span> <a shape="rect" href="#BuildingStruts2-Fasttrackrelease-Cleanupoldreleases">Clean up old releases</a></li><li><span class="TOCOutline">1.12</span> <a shape="rect" href="#BuildingStruts2-Fasttrackrelease-Waitforrsync">Wait for rsync</a></li><li><span class="TOCOutline">1.13</span> <a shape="rect" href="#BuildingStruts2-Fasttrackrelease-(Optional)-UpdateSecurityBulletins">(Optional) - Update Security Bulletins</a></li><li><span class="TOCOu tline">1.14</span> <a shape="rect" href="#BuildingStruts2-Fasttrackrelease-Updatesite(Strutstoplevelsite)">Update site (Struts top level site)</a></li><li><span class="TOCOutline">1.15</span> <a shape="rect" href="#BuildingStruts2-Fasttrackrelease-Updatesite(Struts2site)">Update site (Struts 2 site)</a></li><li><span class="TOCOutline">1.16</span> <a shape="rect" href="#BuildingStruts2-Fasttrackrelease-Postannouncements">Post announcements</a></li></ul> </li></ul>