Cleans up pages
Project: http://git-wip-us.apache.org/repos/asf/struts-site/repo Commit: http://git-wip-us.apache.org/repos/asf/struts-site/commit/b4f6a844 Tree: http://git-wip-us.apache.org/repos/asf/struts-site/tree/b4f6a844 Diff: http://git-wip-us.apache.org/repos/asf/struts-site/diff/b4f6a844 Branch: refs/heads/master Commit: b4f6a844f855379a6c43e5259d3eda265a6d1991 Parents: 116c7b0 Author: Lukasz Lenart <[email protected]> Authored: Fri Aug 25 14:17:49 2017 +0200 Committer: Lukasz Lenart <[email protected]> Committed: Fri Aug 25 14:17:49 2017 +0200 ---------------------------------------------------------------------- ...ssing-application-session-request-objects.md | 110 +--- source/core-developers/action-chaining.md | 93 ++- source/core-developers/action-event-listener.md | 25 +- .../action-mapper-and-action-mapping.md | 34 +- .../action-proxy-and-actionproxy-factory.md | 43 +- source/core-developers/dispatcher-listener.md | 14 +- .../formatting-dates-and-numbers.md | 104 ++-- source/core-developers/index.md | 4 +- source/core-developers/localization.md | 282 +++------ source/core-developers/logging.md | 80 +-- .../core-developers/model-driven-interceptor.md | 74 +-- .../core-developers/parameters-interceptor.md | 246 +++----- source/core-developers/pre-result-listener.md | 28 +- source/core-developers/result-types.md | 94 +-- source/core-developers/static-content.md | 96 +-- source/core-developers/type-conversion.md | 558 +++++++---------- source/core-developers/validation.md | 616 ++++++++++--------- source/core-developers/writing-interceptors.md | 73 +-- 18 files changed, 1061 insertions(+), 1513 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/struts-site/blob/b4f6a844/source/core-developers/accessing-application-session-request-objects.md ---------------------------------------------------------------------- diff --git a/source/core-developers/accessing-application-session-request-objects.md b/source/core-developers/accessing-application-session-request-objects.md index b1f192e..099a6e5 100644 --- a/source/core-developers/accessing-application-session-request-objects.md +++ b/source/core-developers/accessing-application-session-request-objects.md @@ -7,22 +7,15 @@ title: Accessing application, session, request objects **DEPRECATED???** -The framework provides several access helpers to access Session, Application, Request scopes\. +The framework provides several access helpers to access Session, Application, Request scopes. -####Accessing from Java#### +## Accessing from Java -All the JEE scope attribute maps can be accessed via - -~~~~~~~ -ActionContext -~~~~~~~ -\. +All the JEE scope attribute maps can be accessed via `ActionContext`. **Accessing servlet scopes** - -~~~~~~~ - +```java Map attr = (Map) ActionContext.getContext().get("attr"); attr.put("myId",myProp); @@ -34,101 +27,36 @@ session.put("myId", myProp); Map request = (Map) ActionContext.getContext().get("request"); request.put("myId",myProp); +``` -~~~~~~~ - - -> - -> - -> Do not use ActionContext\.getContext() in the constructor of your Action class\. The values may not be set up, and the call may return null for getSession()\. +> Do not use `ActionContext.getContext()` in the constructor of your Action class. The values may not be set up, and +> the call may return null for getSession(). -> - -We can also access the - -~~~~~~~ -HttpServletRequest -~~~~~~~ - and - -~~~~~~~ -HttpServletResponse -~~~~~~~ - objects themselves through - -~~~~~~~ -ServletActionContext -~~~~~~~ -\. In general this isn't recommended as it will tie our action to the servlet specification\. +We can also access the `HttpServletRequest` and `HttpServletResponse` objects themselves through `ServletActionContext`. +In general this isn't recommended as it will tie our action to the servlet specification. **Setting session attribute through session object** - -~~~~~~~ - +```java ServletActionContext.getRequest().getSession().put("myId", myProp); +``` -~~~~~~~ +Implementing `ServletRequestAware` or `ServletResponseAware`, combined with the `servletConfig` interceptor, +is an alternative way to access the request and response objects, with the same caveat. -Implementing +## Accessing from the view (JSP, FreeMarker, etc.) -~~~~~~~ -ServletRequestAware -~~~~~~~ - or +Request and session attributes are accessed via OGNL using the `#session` and `#request` stack values. -~~~~~~~ -ServletResponseAware -~~~~~~~ -, combined with the - -~~~~~~~ -"servletConfig" interceptor -~~~~~~~ -, is an alternative way to access the request and response objects, with the same caveat\. - -####Accessing from the view (JSP, FreeMarker, etc\.)#### - -Request and session attributes are accessed via OGNL using the - -~~~~~~~ -#session -~~~~~~~ - and - -~~~~~~~ -#request -~~~~~~~ - stack values\. - -The - -~~~~~~~ -#attr -~~~~~~~ - stack value will search the - -~~~~~~~ -javax.servlet.jsp.PageContext -~~~~~~~ - for the specified key\. If the - -~~~~~~~ -PageContext -~~~~~~~ - doean't exist, it will search the request, session, and application scopes, in that order\. +The `#attr` stack value will search the `javax.servlet.jsp.PageContext` for the specified key. If the `PageContext` +doean't exist, it will search the request, session, and application scopes, in that order. **Accessing the Session or Request from a JSP** - -~~~~~~~ - +```jsp <s:property value="#session.myId" /> <s:property value="#request.myId" /> <s:property value="#attr.myId" /> - -~~~~~~~ +``` http://git-wip-us.apache.org/repos/asf/struts-site/blob/b4f6a844/source/core-developers/action-chaining.md ---------------------------------------------------------------------- diff --git a/source/core-developers/action-chaining.md b/source/core-developers/action-chaining.md index 5753419..b6f78f2 100644 --- a/source/core-developers/action-chaining.md +++ b/source/core-developers/action-chaining.md @@ -5,33 +5,66 @@ title: Action Chaining # Action Chaining -The framework provides the ability to chain multiple actions into a defined sequence or workflow\. This feature works by applying a [Chain Result](chain-result.html) to a given Action, and intercepting its target Action's invocation with a [Chaining Interceptor](chaining-interceptor.html)\. - - - -| As a rule, Action Chaining is not recommended\. First explore other options, such as the _Redirect After Post_ technique\. - -| - -####Chain Result#### - -The [Chain Result](chain-result.html) is a result type that invokes an Action with its own Interceptor Stack and Result\. This Interceptor allows an Action to forward requests to a target Action, while propagating the state of the source Action\. Below is an example of how to define this sequence\. - - -~~~~~~~ -{snippet:id=example|lang=xml|javadoc=true|url=com.opensymphony.xwork2.ActionChainResult} -~~~~~~~ - -Another action mapping in the same namespace (or the default "" namespace) can be executed after this action mapping (see [Configuration Files](configuration-files.html)). An optional "namespace" parameter may also be added to specify an action in a different namespace\. - -####Chaining Interceptor#### - -If you need to copy the properties from your previous Actions in the chain to the current action, you should apply the [Chaining Interceptor](chaining-interceptor.html)\. The Interceptor will copy the original parameters from the request, and the ValueStack is passed in to the target Action\. The source Action is remembered by the ValueStack, allowing the target Action to access the properties of the preceding Action(s) using the ValueStack, and also makes these properties available to the final result of the chain, such as the JSP or Velocity page\. - -One common use of Action chaining is to provide lookup lists (like for a dropdown list of states)\. Since these Actions get put on the ValueStack, their properties will be available in the view\. This functionality can also be done using the ActionTag to execute an Action from the display page\. You may also use the [Redirect Action Result](redirect-action-result.html) to accomplish this\. - -#####Use with care##### - -Experience shows that chaining should be used with care\. If chaining is overused, an application can turn into "spaghetti code"\. Actions should be treated as a [Transaction Script](http://martinfowler\.com/eaaCatalog/transactionScript\.html)^[http://martinfowler\.com/eaaCatalog/transactionScript\.html], rather than as methods in a [Business Facade](http://msdn2\.microsoft\.com/en\-us/library/aa291571(VS\.71)\.aspx)^[http://msdn2\.microsoft\.com/en\-us/library/aa291571(VS\.71)\.aspx]\. Be sure to ask yourself why you need to chain from one Action to another\. Is a navigational issue, or could the logic in Action2 be pushed back to a support class or business facade so that Action1 can call it too? - -Ideally, Action classes should be as short as possible\. All the core logic should be pushed back to a support class or a business facade, so that Actions only call methods\. Actions are best used as adapters, rather than as a class where coding logic is defined\. +The framework provides the ability to chain multiple actions into a defined sequence or workflow. This feature works +by applying a [Chain Result](chain-result.html) to a given Action, and intercepting its target Action's invocation +with a [Chaining Interceptor](chaining-interceptor.html). + +> As a rule, Action Chaining is not recommended. First explore other options, such as the `Redirect After Post` technique. + +## Chain Result + +The [Chain Result](chain-result.html) is a result type that invokes an Action with its own Interceptor Stack and Result. +This Interceptor allows an Action to forward requests to a target Action, while propagating the state of the source Action. +Below is an example of how to define this sequence. + +```xml +<package name="public" extends="struts-default"> + <!-- Chain creatAccount to login, using the default parameter --> + <action name="createAccount" class="..."> + <result type="chain">login</result> + </action> + + <action name="login" class="..."> + <!-- Chain to another namespace --> + <result type="chain"> + <param name="actionName">dashboard</param> + <param name="namespace">/secure</param> + </result> + </action> +</package> + +<package name="secure" extends="struts-default" namespace="/secure"> + <action name="dashboard" class="..."> + <result>dashboard.jsp</result> + </action> +</package> +``` + +Another action mapping in the same namespace (or the default "" namespace) can be executed after this action mapping +(see [Configuration Files](configuration-files.html)). An optional "namespace" parameter may also be added to specify +an action in a different namespace. + +## Chaining Interceptor + +If you need to copy the properties from your previous Actions in the chain to the current action, you should apply +the [Chaining Interceptor](chaining-interceptor.html). The Interceptor will copy the original parameters from the request, +and the ValueStack is passed in to the target Action. The source Action is remembered by the ValueStack, allowing +the target Action to access the properties of the preceding Action(s) using the ValueStack, and also makes these +properties available to the final result of the chain, such as the JSP or Velocity page. + +One common use of Action chaining is to provide lookup lists (like for a dropdown list of states). Since these Actions +get put on the ValueStack, their properties will be available in the view. This functionality can also be done using +the ActionTag to execute an Action from the display page. You may also use +the [Redirect Action Result](redirect-action-result.html) to accomplish this. + +## Use with care + +Experience shows that chaining should be used with care. If chaining is overused, an application can turn into +"spaghetti code". Actions should be treated as a [Transaction Script](http://martinfowler.com/eaaCatalog/transactionScript.html), +rather than as methods in a [Business Facade](http://msdn2.microsoft.com/en\-us/library/aa291571(VS.71).aspx). Be sure +to ask yourself why you need to chain from one Action to another. Is a navigational issue, or could the logic in Action2 +be pushed back to a support class or business facade so that Action1 can call it too? + +Ideally, Action classes should be as short as possible. All the core logic should be pushed back to a support class +or a business facade, so that Actions only call methods. Actions are best used as adapters, rather than as a class +where coding logic is defined. http://git-wip-us.apache.org/repos/asf/struts-site/blob/b4f6a844/source/core-developers/action-event-listener.md ---------------------------------------------------------------------- diff --git a/source/core-developers/action-event-listener.md b/source/core-developers/action-event-listener.md index 3b45b16..70ea46e 100644 --- a/source/core-developers/action-event-listener.md +++ b/source/core-developers/action-event-listener.md @@ -5,25 +5,21 @@ title: ActionEventListener # ActionEventListener -A ActionEventListener can be used to add some logic when action's instance is created or when exception occurred during processing the action\. +An `ActionEventListener` can be used to add some logic when action's instance is created or when exception occurred +during processing the action. -#####Configuration##### +## Configuration -Right now there can be only one instance of ActionEventListener for the whole Struts2 application\. You can configure it via struts\.xml by adding bean definition: - - -~~~~~~~ +Right now there can be only one instance of `ActionEventListener` for the whole Struts2 application. You can configure +it via `struts.xml` by adding bean definition: +```xml <bean type="com.opensymphony.xwork2.ActionEventListener" class="com.demo.MyActionEventListener"/> +``` -~~~~~~~ - -#####Examples##### - - - -~~~~~~~ +## Examples +```java public class MyActionEventListener implements ActionEventListener { public Object prepare(Object action, ValueStack stack) { @@ -39,5 +35,4 @@ public class MyActionEventListener implements ActionEventListener { return null; } } - -~~~~~~~ +``` http://git-wip-us.apache.org/repos/asf/struts-site/blob/b4f6a844/source/core-developers/action-mapper-and-action-mapping.md ---------------------------------------------------------------------- diff --git a/source/core-developers/action-mapper-and-action-mapping.md b/source/core-developers/action-mapper-and-action-mapping.md index 4fea296..5971945 100644 --- a/source/core-developers/action-mapper-and-action-mapping.md +++ b/source/core-developers/action-mapper-and-action-mapping.md @@ -5,33 +5,20 @@ title: Action Mapper & Action Mapping # Action Mapper & Action Mapping -The ActionMapper fetches the ActionMapping object corresponding to a given request\. Essentially, the ActionMapping is a data transfer object that collects together details such as the Action class and method to execute\. The mapping is utilized by the Dispatcher and various user interface components\. It is customizable through +The ActionMapper fetches the ActionMapping object corresponding to a given request. Essentially, the ActionMapping +is a data transfer object that collects together details such as the Action class and method to execute. The mapping +is utilized by the Dispatcher and various user interface components. It is customizable through `struts.mapper.class` +entry in `struts.properties`. -~~~~~~~ -struts.mapper.class -~~~~~~~ - entry in +## Customize -~~~~~~~ -struts.properties -~~~~~~~ -\. - -####Customize#### - -Custom ActionMapper must implement ActionMapper interface and have a default constructor\. - -> - -~~~~~~~ +Custom ActionMapper must implement ActionMapper interface and have a default constructor. +``` struts.mapper.class=foo.bar.MyCustomActionMapper +``` -~~~~~~~ - - -~~~~~~~ - +```java public class MyCustomActionMapper implements ActionMapper { public ActionMapping getMapping(HttpServletRequest request, ConfigurationManager configManager) { @@ -42,5 +29,4 @@ public class MyCustomActionMapper implements ActionMapper { .... } } - -~~~~~~~ +``` http://git-wip-us.apache.org/repos/asf/struts-site/blob/b4f6a844/source/core-developers/action-proxy-and-actionproxy-factory.md ---------------------------------------------------------------------- diff --git a/source/core-developers/action-proxy-and-actionproxy-factory.md b/source/core-developers/action-proxy-and-actionproxy-factory.md index f302bd1..d8ae9bc 100644 --- a/source/core-developers/action-proxy-and-actionproxy-factory.md +++ b/source/core-developers/action-proxy-and-actionproxy-factory.md @@ -5,36 +5,34 @@ title: Action Proxy & ActionProxy Factory # Action Proxy & ActionProxy Factory -The ActionProxy obtains the Action class and calls the appropriate method\. By default, Actions are obtained through local instantiation, but an Action could also be obtained remotely if an alternative ActionProxy were provided\. +The ActionProxy obtains the Action class and calls the appropriate method. By default, Actions are obtained through +local instantiation, but an Action could also be obtained remotely if an alternative ActionProxy were provided. -An alternative ActionProxy can be configured through ActionProxyFactory\. Typically, an ActionProxy will utilize the ActionInvocation to encapsulate the execution of a particular request\. +An alternative ActionProxy can be configured through ActionProxyFactory. Typically, an ActionProxy will utilize +the ActionInvocation to encapsulate the execution of a particular request. -The ActionInvocation determines how an Action is handled: Is it being intercepted? Is there a PreResultListener acting on it? +The ActionInvocation determines how an Action is handled: Is it being intercepted? Is there a PreResultListener +acting on it? -Essentially, ActionProxy encapsulates how an Action can be obtained\. ActionInvocation encapsulates how the Action is executed when a request is invoked\. +Essentially, ActionProxy encapsulates how an Action can be obtained. ActionInvocation encapsulates how the Action +s executed when a request is invoked. -####Customization#### +## Customization -#####ActionProxyFactory##### +### ActionProxyFactory - -~~~~~~~ - +```java ActionProxyFactory.setFactory(new MyActionProxyFactory() { // Do something interesting... }); +``` -~~~~~~~ - -#####ActionProxy##### - - - -~~~~~~~ +### ActionProxy +````java ActionProxyFactory.getFactory(new MyActionProxyFactory() { .... public ActionProxy createActionProxy(Configuration config, @@ -50,15 +48,11 @@ Essentially, ActionProxy encapsulates how an Action can be obtained\. ActionInvo } .... }); +```` -~~~~~~~ - -#####ActionInvocation##### - - - -~~~~~~~ +### ActionInvocation +```java ActionProxyFactory.getFactory(new MyActionProxyFactory() { ... public ActionInvocation createActionInvocation(ActionProxy actionProxy) @@ -77,5 +71,4 @@ Essentially, ActionProxy encapsulates how an Action can be obtained\. ActionInvo } ... }); - -~~~~~~~ +``` http://git-wip-us.apache.org/repos/asf/struts-site/blob/b4f6a844/source/core-developers/dispatcher-listener.md ---------------------------------------------------------------------- diff --git a/source/core-developers/dispatcher-listener.md b/source/core-developers/dispatcher-listener.md index 456db3c..c8cf537 100644 --- a/source/core-developers/dispatcher-listener.md +++ b/source/core-developers/dispatcher-listener.md @@ -5,14 +5,13 @@ title: DispatcherListener # DispatcherListener -Use a DispatcherListener object to execute code when a Dispatcher is initalized or destroyed\. A DispatcherListener is an easy way to associate customizable components like a [ConfigurationManager](configuration-provider-and-configuration.html) with a Dispatcher\. +Use a `DispatcherListener` object to execute code when a Dispatcher is initialized or destroyed. A `DispatcherListener` +is an easy way to associate customizable components like a [ConfigurationManager](configuration-provider-and-configuration.html) +with a Dispatcher. -####Example#### - - - -~~~~~~~ +## Example +```java static { Dispatcher.addDispatcherListener(new DispatcherListener() { public void dispatcherInitialized(Dispatcher du) { @@ -25,5 +24,4 @@ Use a DispatcherListener object to execute code when a Dispatcher is initalized } }); } - -~~~~~~~ +``` http://git-wip-us.apache.org/repos/asf/struts-site/blob/b4f6a844/source/core-developers/formatting-dates-and-numbers.md ---------------------------------------------------------------------- diff --git a/source/core-developers/formatting-dates-and-numbers.md b/source/core-developers/formatting-dates-and-numbers.md index e96a212..23f3f6f 100644 --- a/source/core-developers/formatting-dates-and-numbers.md +++ b/source/core-developers/formatting-dates-and-numbers.md @@ -5,107 +5,89 @@ title: Formatting Dates and Numbers # Formatting Dates and Numbers -####Defining Formats#### +## Defining Formats -Struts2 supports localization (l10n) aware formatting of dates, times and numbers very easily, utilizing Java's built\-in date formatting features\. +Struts2 supports localization (l10n) aware formatting of dates, times and numbers very easily, utilizing Java's +built-in date formatting features. -As seen in the [Localization](#PAGE_14043) chapter, it is quite easy to define hierarchical resource bundles with Struts2, giving the developer the opportunity to define locale dependent message formats\. This is the entry point to define the needed date, time and number formats\. Your default properties could contain the following generic formats: - - -~~~~~~~ +As seen in the [Localization](localization.html) chapter, it is quite easy to define hierarchical resource bundles +with Struts2, giving the developer the opportunity to define locale dependent message formats. This is the entry point +to define the needed date, time and number formats. Your default properties could contain the following generic formats: +``` format.time = {0,time} format.number = {0,number,#0.0##} format.percent = {0,number,##0.00'%'} format.money = {0,number,\u00A4##0.00} +``` -~~~~~~~ - -An appropriate en\_US format definition extension could look like this: - - -~~~~~~~ +An appropriate en_US format definition extension could look like this: +``` format.date = {0,date,MM/dd/yy} +``` -~~~~~~~ - -In parallel, you could add the following to your de\_DE bundle: - - -~~~~~~~ +In parallel, you could add the following to your de_DE bundle: +``` format.date = {0,date,dd.MM.yyyy} +``` -~~~~~~~ - -Read more on how to define message formats in Sun's Java API docs for [MessageFormat](http://java\.sun\.com/j2se/1\.5\.0/docs/api/java/text/MessageFormat\.html)^[http://java\.sun\.com/j2se/1\.5\.0/docs/api/java/text/MessageFormat\.html]\. - -Now that we have our formats set up, it is quite easy to use them in our views\. - -####Formatting output using the s:text tag#### +Read more on how to define message formats in Sun's Java API docs for [MessageFormat](http://java.sun.com/j2se/1.5.0/docs/api/java/text/MessageFormat.html). -Given you had a Float value myMoneyValue, accessible through the getter getMyMoneyValue in your action, the following code would print out localized representation of the value as a currency amount, using the format\.money message format defined above with a _s:text_ tag: +Now that we have our formats set up, it is quite easy to use them in our views. +## Formatting output using the s:text tag -~~~~~~~ +Given you had a Float value myMoneyValue, accessible through the getter getMyMoneyValue in your action, the following +code would print out localized representation of the value as a currency amount, using the format.money message +format defined above with a `s:text` tag: +```jsp <s:text name="format.money"> <s:param name="value" value="myMoneyValue"/> </s:text> +``` -~~~~~~~ - -The (first) parameter defines the value which is to replace the '0' placeholder in the defined message format\. +The (first) parameter defines the value which is to replace the '0' placeholder in the defined message format. Another example, formatting a date value: - -~~~~~~~ - +```jsp <s:text name="format.date"><s:param value="dueDate"/></s:text> +``` -~~~~~~~ +> While the `s:text` tag is very useful to format numbers, date formatting has become a lot easier thanks +> to the `s:date` tag. - - -| While the s:text tag is very useful to format numbers, date formatting has become a lot easier thanks to the _s:date_ tag\. - -| - -####Localizing form data with getText#### +## Localizing form data with getText Placing a textfield in a form like this - -~~~~~~~ - +```jsp <s:textfield key="orderItem.price" /> +``` -~~~~~~~ - -to input a number, one might have noticed that the number is always shown in the Java default number format\. Not only that this is not "nice", if you are in a non\-en locale, it will also cause trouble when submitting the form since type conversion is locale aware\. The solution is to again use the message formats as defined above, by using the getText Method of ActionSupport: - - -~~~~~~~ +to input a number, one might have noticed that the number is always shown in the Java default number format. Not only +that this is not "nice", if you are in a non-en locale, it will also cause trouble when submitting the form since type +conversion is locale aware. The solution is to again use the message formats as defined above, by using the getText +method of ActionSupport: +```jsp <s:textfield key="orderItem.price" value="%{getText('format.number',{orderItem.price})}" /> +``` -~~~~~~~ - -This maps to the method signature getText( String key, Object\[\] params ) in ActionSupport\. +This maps to the method signature `getText( String key, Object[] params )` in ActionSupport. -####Using getFormatted() with conversion support#### +## Using getFormatted() with conversion support -A new method getFormatted was added to ActionSupport (which can be implemented in your base action) to support formatting and conversion errors with I10N\. +A new method getFormatted was added to ActionSupport (which can be implemented in your base action) to support +formatting and conversion errors with I10N. You can place a code like below - -~~~~~~~ - +```jsp <s:textfield key="user.born" value="%{getFormatted('format.number','user.born')}" /> +``` -~~~~~~~ - -to get support for I10N and also to support conversion errors\. +to get support for I10N and also to support conversion errors. http://git-wip-us.apache.org/repos/asf/struts-site/blob/b4f6a844/source/core-developers/index.md ---------------------------------------------------------------------- diff --git a/source/core-developers/index.md b/source/core-developers/index.md index 87c2d36..3acfc26 100644 --- a/source/core-developers/index.md +++ b/source/core-developers/index.md @@ -61,6 +61,6 @@ Each may be configured via XML or annotations. - [Accessing application, session, request objects](accessing-application-session-request-objects.html) - [Action Mapper & Action Mapping](action-mapper-and-action-mapping.html) - [Action Proxy & ActionProxy Factory](action-proxy-and-actionproxy-factory.html) -- [FAQs] - - [Struts 2 Maven Archetypes](#PAGE_108820)\ +- [FAQs](../faq/) + - [Struts 2 Maven Archetypes](../maven-archetypes/) - [Cookbook] http://git-wip-us.apache.org/repos/asf/struts-site/blob/b4f6a844/source/core-developers/localization.md ---------------------------------------------------------------------- diff --git a/source/core-developers/localization.md b/source/core-developers/localization.md index ad265e1..647d53c 100644 --- a/source/core-developers/localization.md +++ b/source/core-developers/localization.md @@ -5,259 +5,147 @@ title: Localization # Localization - -####Overview#### +## Overview The framework supports internationalization (i18n) in the following places: 1. the _UI Tags_ +2. Messages and Errors from the [ValidationAware](http://struts.apache.org/struts2-core/apidocs/index.html?com/opensymphony/xwork2/ValidationAware.html) +3. Within action classes that extend [ActionSupport](http://struts.apache.org/struts2-core/apidocs/index.html?com/opensymphony/xwork2/ActionSupport.html) through the `getText()` method -2. Messages and Errors from the [ValidationAware](http://struts.apache.org/2.0.6/struts2-core/apidocs/index.html?com/opensymphony/xwork2/ValidationAware.html)^[http://struts.apache.org/2.0.6/struts2-core/apidocs/index.html?com/opensymphony/xwork2/ValidationAware.html] interface (implemented by [ActionSupport](http://struts.apache.org/2.0.6/struts2-core/apidocs/index.html?com/opensymphony/xwork2/ActionSupport.html)^[http://struts.apache.org/2.0.6/struts2-core/apidocs/index.html?com/opensymphony/xwork2/ActionSupport.html] and [ValidationAwareSupport](http://struts.apache.org/2.0.6/struts2-core/apidocs/index.html?com/opensymphony/xwork2/ValidationAwareSupport.html)^[http://struts.apache.org/2.0.6/struts2-core/apidocs/index.html?com/opensymphony/xwork2/ValidationAwareSupport.html]) - -3. Within action classes that extend [ActionSupport](http://struts.apache.org/2.0.6/struts2-core/apidocs/index.html?com/opensymphony/xwork2/ActionSupport.html)^[http://struts.apache.org/2.0.6/struts2-core/apidocs/index.html?com/opensymphony/xwork2/ActionSupport.html] through the getText() method - -####Resource Bundle Search Order#### +## Resource Bundle Search Order Resource bundles are searched in the following order: -1. - -~~~~~~~ -ActionClass -~~~~~~~ -.properties - -2. - -~~~~~~~ -Interface -~~~~~~~ -.properties (every interface and sub-interface) - -3. - -~~~~~~~ -BaseClass -~~~~~~~ -.properties (all the way to Object.properties) - +1. `ActionClass`.properties +2. `Interface`.properties (every interface and sub-interface) +3. `BaseClass`.properties (all the way to Object.properties) 4. ModelDriven's model (if implements ModelDriven), for the model object repeat from 1 - 5. package.properties (of the directory where class is located and every parent directory all the way to the root directory) - 6. search up the i18n message key hierarchy itself - 7. global resource properties -This is how it is implemented in a default implementation of the - -~~~~~~~ -LocalizedTextProvider -~~~~~~~ - interface\. You can provide your own implementation using - -~~~~~~~ -TextProvider -~~~~~~~ - and - -~~~~~~~ -TextProviderFactory -~~~~~~~ - interfaces\. - - +This is how it is implemented in a default implementation of the `LocalizedTextProvider` interface. You can provide your +own implementation using `TextProvider` and `TextProviderFactory` interfaces. -| To clarify \#5, while traversing the package hierarchy, Struts 2 will look for a file package\.properties: +To clarify #5, while traversing the package hierarchy, Struts 2 will look for a file `package.properties`: -| com/ - acme/ - package\.properties +``` +com/ + acme/ + package.properties actions/ - package\.properties - FooAction\.java - FooAction\.properties + package.properties + FooAction.java + FooAction.properties +``` -| +> If `FooAction.properties` does not exist, `com/acme/action/package.properties` will be searched for, if not found +> `com/acme/package.properties`, if not found `com/package.properties`, etc. -| If FooAction\.properties does not exist, com/acme/action/package\.properties will be searched for, if not found com/acme/package\.properties, if not found com/package\.properties, etc\. - -| - -#####Default action's class##### +## Default action's class If you configure action as follow - -~~~~~~~ +```xml <action name="index"> <result>/index.jsp</result> </action> -~~~~~~~ - -it will use a default class defined with - -~~~~~~~ -default-class-ref -~~~~~~~ - in +``` -~~~~~~~ -struts-default.xml -~~~~~~~ - which is +it will use a default class defined with `default-class-ref` in `struts-default.xml` which is +`com.opensymphony.xwork2.ActionSupport`. It means you have two options here to get I18N working in that case: -~~~~~~~ -com.opensymphony.xwork2.ActionSupport -~~~~~~~ -\. It means you have two options here to get I18N working in that case: +- define `com/opensymphony/xwork2/ActionSupport.properties` and put messages there +- point `default-class-ref` to your base class and then defined appropriated `.properties` file (corresponding to + class' name or package) -+ define +## Examples -~~~~~~~ -com/opensymphony/xwork2/ActionSupport.properties -~~~~~~~ - and put messages there +There are several ways to access the message resources, including `getText`, the `text` tag, and the `i18n` tag. -+ point +### Using getText from a Tag -~~~~~~~ -default-class-ref -~~~~~~~ - to your base class and then defined appropriated +To display i18n text, use a call to `getText` in the `property` tag, or any other tag, such as the UI tags. (The `getText` +technique is especially useful for labels of UI tags.) -~~~~~~~ -.properties -~~~~~~~ - file (corresponding to class' name or package) +```xml +<s:property value="getText('some.key')" /> +``` - Examples +The default implementation of `TextProvider` which is used in `ActionSupport` perform evaluation of value read from +bundle base on the provided key, see [Localizing Output] for an example. - There are several ways to access the message resources, including +### Using the text tag -~~~~~~~ -getText -~~~~~~~ -, the +The `text` tag retrieves a message from the default resource bundle. -~~~~~~~ -text -~~~~~~~ - tag, and the +```xml +<s:text name="some.key" /> -~~~~~~~ -i18n -~~~~~~~ - tag\. +<s:text name="some.invalid.key"> + The Default Message That Will Be Displayed +</s:text> +``` -#####Using getText from a Tag##### +### Using the I18n tag -To display i18n text, use a call to +The `i18n` tag pushes an arbitrary resource bundle on to the value stack. Other tags within the scope of the i18n tag +can display messages from that resource bundle. -~~~~~~~ -getText -~~~~~~~ - in the _property_ tag, or any other tag, such as the UI tags\. (The +```xml +<s:i18n name="some.package.bundle"></s:i18n> + <s:text name="some.key" /> +</s:i18n> +``` -~~~~~~~ -getText -~~~~~~~ - technique is especially useful for labels of UI tags\.) +Internationalizing SiteMesh decorators is possible, but there are quirks. See [SiteMesh Plugin](../plugins/sitemesh/) +for more. -~~~~~~~ -{snippet:id=i18nExample|javadoc=true|lang=xml|url=org.apache.struts2.components.Property} -~~~~~~~ - - -The default implementation of TextProvider which is used in ActionSupport perform evaluation of value read from bundle base on the provided key, see _Localizing Output_ for an example\. - -| - -#####Using the text tag##### - -The _text_ tag retrieves a message from the default resource bundle\. - -~~~~~~~ -{snippet:id=i18nExample|javadoc=true|lang=xml|url=org.apache.struts2.components.Text} -~~~~~~~ - -#####Using the I18n tag##### - -The _i18n_ tag pushes an arbitrary resource bundle on to the value stack\. Other tags within the scope of the i18n tag can display messages from that resource bundle\. - -~~~~~~~ -{snippet:id=i18nExample|javadoc=true|lang=xml|url=org.apache.struts2.components.I18n} -~~~~~~~ - - -Internationalizing SiteMesh decorators is possible, but there are quirks\. See _SiteMesh Plugin_ for more\. - -| - -#####Using the Key attribute of UI Tags##### +### Using the Key attribute of UI Tags The key attribute of most UI tags can be used to retrieve a message from a resource bundle: - -~~~~~~~ +```xml <s:textfield key="some.key" name="textfieldName"/> -~~~~~~~ - -####I18n Interceptor#### - -Essentially, the i18n Interceptor pushes a locale into the ActionContext map upon every request\. The framework components that support localization all utilize the ActionContext locale\. See [I18n Interceptor](i18n-interceptor.html) for details\. +``` -####Global Resources (struts\.custom\.i18n\.resources) in struts\.properties#### +## I18n Interceptor -A global resource bundle could be specified programmatically, as well as the locale\. +Essentially, the i18n Interceptor pushes a locale into the ActionContext map upon every request. The framework +components that support localization all utilize the ActionContext locale. See [I18n Interceptor](i18n-interceptor.html) f +or details. -####Formatting Dates and Numbers#### +## Global Resources (struts.custom.i18n.resources) in struts.properties -See [Formatting Dates and Numbers](formatting-dates-and-numbers.html) for more details and examples\. +A global resource bundle could be specified programmatically, as well as the locale. -####Comparison with Struts 1#### +## Formatting Dates and Numbers -Struts 1 users should be familiar with the application\.properties resource bundle, where you can put all the messages in the application that are going to be translated\. Struts 2, though, splits the resource bundles per action or model class, and you may end up with duplicated messages in those resource bundles\. A quick fix for that is to create a file called ActionSupport\.properties in com/opensymphony/xwork2 and put it on your classpath\. This will only work well if all your actions subclass XWork2's ActionSupport\. +See [Formatting Dates and Numbers](formatting-dates-and-numbers.html) for more details and examples. -####Using only global bundles#### +## Comparison with Struts 1 -If you don't need to use the package\-scan\-functionality and only base on the global bundles (those provided by the framework and via +Struts 1 users should be familiar with the application.properties resource bundle, where you can put all the messages +in the application that are going to be translated. Struts 2, though, splits the resource bundles per action or model +class, and you may end up with duplicated messages in those resource bundles. A quick fix for that is to create a file +called ActionSupport.properties in com/opensymphony/xwork2 and put it on your classpath. This will only work well if +all your actions subclass XWork2's ActionSupport. -~~~~~~~ -struts.custom.i18n.resources -~~~~~~~ -) you can use existing +## Using only global bundles -~~~~~~~ -GlobalLocalizedTextProvider -~~~~~~~ - implementation\. To use this please define the following option in your +If you don't need to use the package-scan-functionality and only base on the global bundles (those provided by +the framework and via `struts.custom.i18n.resources`) you can use existing `GlobalLocalizedTextProvider` +implementation. To use this please define the following option in your `struts.xml`: -~~~~~~~ -struts.xml -~~~~~~~ -: - - -~~~~~~~ +```xml <constant name="struts.localizedTextProvider" value="global-only" /> -~~~~~~~ - -####Custom TextProvider and TextProviderFactory#### - -If you want use a different logic to search for localized messages, or you want to use a database or just want to search default bundles, you must implement both those interfaces (or subclass the existing implementations)\. You can check a small [example app](https://github\.com/apache/struts\-examples/tree/master/text\-provider)^[https://github\.com/apache/struts\-examples/tree/master/text\-provider] how to use both\. Please remember that the - -~~~~~~~ -TextProvider -~~~~~~~ - interface is implemented by the +``` -~~~~~~~ -ActioSupport -~~~~~~~ - class, that's why an extra layer \- +## Custom TextProvider and TextProviderFactory -~~~~~~~ -TextProviderFactory -~~~~~~~ - \- is needed\. +If you want use a different logic to search for localized messages, or you want to use a database or just want to search +default bundles, you must implement both those interfaces (or subclass the existing implementations). You can check +a small [example app](https://github.com/apache/struts\-examples/tree/master/text\-provider) how to use both. +Please remember that the `TextProvider` interface is implemented by the `ActionSupport` class, that's why +an extra layer - `TextProviderFactory` - is needed. http://git-wip-us.apache.org/repos/asf/struts-site/blob/b4f6a844/source/core-developers/logging.md ---------------------------------------------------------------------- diff --git a/source/core-developers/logging.md b/source/core-developers/logging.md index da92563..ba231af 100644 --- a/source/core-developers/logging.md +++ b/source/core-developers/logging.md @@ -5,28 +5,28 @@ title: Logging # Logging -#####Logging support##### +## Logging support -XWork provides its own layer to support logging \- it allows to use many different implementations\. +> As from Struts 2.5 version, the logging layer is deprecated and Struts uses Log4j2 +> The logging layer will be dropped with the next major release. -Currently XWork provides support for the following libraries (in that order base on classpath discovery): - -+ Commons Logging +XWork provides its own layer to support logging - it allows to use many different implementations. -+ [SLF4J](http://www\.slf4j\.org/)^[http://www\.slf4j\.org/] - -+ [Log4j2](http://logging\.apache\.org/log4j/2\.x/)^[http://logging\.apache\.org/log4j/2\.x/] +Currently XWork provides support for the following libraries (in that order base on classpath discovery): -+ JDK Logger +- Commons Logging +- [SLF4J](http://www.slf4j.org/) +- [Log4j2](http://logging.apache.org/log4j/2.x/) +- JDK Logger -__Usage__ +## Usage -To use given type of library add it as a Maven dependency or drop into WEB\-INF/lib folder\. XWork LoggerFactory class will use given logging provider if available\. +To use given type of library add it as a Maven dependency or drop into WEB-INF/lib folder. XWork LoggerFactory class will +use given logging provider if available. To add logging to your application simply declare a Logger as follow: - -~~~~~~~ +```java import com.opensymphony.xwork2.util.logging.Logger; import com.opensymphony.xwork2.util.logging.LoggerFactory; @@ -44,17 +44,16 @@ public class MyAction { // getter / setter } +``` -~~~~~~~ - -__Implementing my own factory__ +## Implementing my own factory -You plug in your own logging solution, simple extend LoggerFactory class and provide a delegate which implements Logger interface, like below: +You plug in your own logging solution, simple extend LoggerFactory class and provide a delegate which implements Logger +interface, like below: **JdkLoggerFactory which adds support for JDK logging** - -~~~~~~~ +```java import com.opensymphony.xwork2.util.logging.Logger; import com.opensymphony.xwork2.util.logging.LoggerFactory; @@ -73,12 +72,11 @@ public class JdkLoggerFactory extends LoggerFactory { return new JdkLogger(java.util.logging.Logger.getLogger(name)); } } +``` -~~~~~~~ - -**JdkLogger is a wrapper around java\.util\.logging\.Logger and implements Logger interface** - +**JdkLogger is a wrapper around java.util.logging.Logger and implements Logger interface** +```java ~~~~~~~ import com.opensymphony.xwork2.util.logging.Logger; import com.opensymphony.xwork2.util.logging.LoggerUtils; @@ -106,40 +104,30 @@ public class JdkLogger implements Logger { ... } +``` -~~~~~~~ - -Check [the source code](http://struts\.apache\.org/2\.x/xwork\-core/apidocs/com/opensymphony/xwork2/util/logging/package\-summary\.html)^[http://struts\.apache\.org/2\.x/xwork\-core/apidocs/com/opensymphony/xwork2/util/logging/package\-summary\.html] to see more details\. +Check [the source code](http://struts.apache.org/struts-core/apidocs/com/opensymphony/xwork2/util/logging/package-summary.html) +to see more details. -__Defining which factory to use__ +## Defining which factory to use Now you must tell XWork/Struts2 to use your implementation, just define system property like below: - - -~~~~~~~ +``` -Dxwork.loggerFactory=com.demo.MyLoggerFactory -~~~~~~~ - -you can use the same to explicit tell the framework which implementation to use and don't depend on class discovery, eg\.: +``` +you can use the same to explicit tell the framework which implementation to use and don't depend on class discovery, eg.: - -~~~~~~~ +``` -Dxwork.loggerFactory=com.opensymphony.xwork2.util.logging.slf4j.Slf4jLoggerFactory -~~~~~~~ - +``` - -~~~~~~~ or -~~~~~~~ - - -~~~~~~~ +``` -Dxwork.loggerFactory=com.opensymphony.xwork2.util.logging.log4j2.Log4j2LoggerFactory -~~~~~~~ - -will enable Slf4j or Log4j2 even if there is commons\-logging on classpath available (commons\-logging is the first LoggerFactory to look for)\. +``` +will enable Slf4j or Log4j2 even if there is commons-logging on classpath available (commons-logging is the first +LoggerFactory to look for). http://git-wip-us.apache.org/repos/asf/struts-site/blob/b4f6a844/source/core-developers/model-driven-interceptor.md ---------------------------------------------------------------------- diff --git a/source/core-developers/model-driven-interceptor.md b/source/core-developers/model-driven-interceptor.md index 9dca496..0175096 100644 --- a/source/core-developers/model-driven-interceptor.md +++ b/source/core-developers/model-driven-interceptor.md @@ -5,62 +5,44 @@ title: Model Driven Interceptor # Model Driven Interceptor +Watches for `ModelDriven` actions and adds the action's model on to the value stack. +> The `ModelDrivenInterceptor` must come before the both `StaticParametersInterceptor` and `ParametersInterceptor` +> if you want the parameters to be applied to the model. -~~~~~~~ -{snippet:id=description|javadoc=true|url=com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor} -~~~~~~~ +> The `ModelDrivenInterceptor` will only push the model into the stack when the model is not null, else it will be ignored. +To create a Model Driven action, implement the `ModelDriven` interface by adding a model property, or at least the accessor. +```java +public Object getModel(); +``` -| To create a Model Driven action, implement the ModelDriven interface by adding a model property, or at least the accessor\. +In the implementation of `getModel`, acquire an instance of a business object and return it. -| +On the page, you can address any JavaBean properties on the business object as if they were coded directly on the Action +class. The framework pushes the Model object onto the ValueStack. -| +Many developers use Spring to acquire the business object. With the addition of a `setModel` method, the business logic +can be injected automatically. -| public Object getModel() \.\.\. +## Parameters -| +- `refreshModelBeforeResult` - set to true if you want the model to be refreshed on the value stack after action + execution and before result execution. The setting is useful if you want to change the model instance during the + action execution phase, like when loading it from the data layer. This will result in `getModel()` being called at + least twice. -| +## Extending the Interceptor -| In the implementation of getModel, acquire an instance of a business object and return it\. +There are no known extension points to this interceptor. -| +## Examples -| - -| On the page, you can address any JavaBean properties on the business object as if they were coded directly on the Action class\. (The framework pushes the Model object onto the ValueStack\.) - -| - -| - -| Many developers use Spring to acquire the business object\. With the addition of a setModel method, the business logic can be injected automatically\. - -| - -#####Parameters##### - - - -~~~~~~~ -{snippet:id=parameters|javadoc=true|url=com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor} -~~~~~~~ - -#####Extending the Interceptor##### - - - -~~~~~~~ -{snippet:id=extending|javadoc=true|url=com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor} -~~~~~~~ - -#####Examples##### - - - -~~~~~~~ -{snippet:id=example|lang=xml|javadoc=true|url=com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor} -~~~~~~~ +```xml +<action name="someAction" class="com.examples.SomeAction"> + <interceptor-ref name="modelDriven"/> + <interceptor-ref name="basicStack"/> + <result name="success">good_result.ftl</result> + </action> +``` http://git-wip-us.apache.org/repos/asf/struts-site/blob/b4f6a844/source/core-developers/parameters-interceptor.md ---------------------------------------------------------------------- diff --git a/source/core-developers/parameters-interceptor.md b/source/core-developers/parameters-interceptor.md index 7f50afa..f944af3 100644 --- a/source/core-developers/parameters-interceptor.md +++ b/source/core-developers/parameters-interceptor.md @@ -5,224 +5,122 @@ title: Parameters Interceptor # Parameters Interceptor -This interceptor sets all parameters on the value stack\. +This interceptor sets all parameters on the value stack. -This interceptor gets all parameters from \{@link ActionContext\#getParameters()\} and sets them on the value stack by calling +This interceptor gets all parameters from `ActionContext#getParameters()` and sets them on the value stack by calling +`ValueStack#setValue(String, Object)`, typically resulting in the values submitted in a form request being applied +to an action in the value stack. Note that the parameter map must contain a `String` key and often containers a `String[]` +for the value. -~~~~~~~ -ValueStack#setValue(String, Object) -~~~~~~~ -, typically resulting in the values submitted in a form request being applied to an action in the value stack\. Note that the parameter map must contain a String key and often containers a String\[\] for the value\. +The interceptor takes one parameter named `ordered`. When set to true action properties are guaranteed to be set top-down +which means that top action's properties are set first. Then it's subcomponents properties are set. The reason for this +order is to enable a "factory" pattern. For example, let's assume that one has an action that contains a property named +`modelClass` that allows to choose what is the underlying implementation of model. By assuring that `modelClass` +property is set before any model properties are set, it's possible to choose model implementation during +`action.setModelClass()` call. Similarly it's possible to use `action.setPrimaryKey()` property set call to actually +load the model class from persistent storage. Without any assumption on parameter order you have to use patterns +like [Preparable Interface](prepare-interceptor.html). -The interceptor takes one parameter named 'ordered'\. When set to true action properties are guaranteed to be set top\-down which means that top action's properties are set first\. Then it's subcomponents properties are set\. The reason for this order is to enable a 'factory' pattern\. For example, let's assume that one has an action that contains a property named +Because parameter names are effectively OGNL statements, it is important that security be taken in to account. This +interceptor will not apply any values in the parameters map if the expression contains an assignment (=), multiple +expressions (,), or references any objects in the context (#). This is all done in the `#acceptableName(String)` +method. In addition to this method, if the action being invoked implements the `ParameterNameAware` interface, the action +will be consulted to determine if the parameter should be set. -~~~~~~~ -modelClass -~~~~~~~ - that allows to choose what is the underlying implementation of model\. By assuring that +In addition to these restrictions, a flag (`ReflectionContextState#DENY_METHOD_EXECUTION`) is set such that no methods +are allowed to be invoked. That means that any expression such as `person.doSomething()` or `person.getName()` will be +explicitly forbidden. This is needed to make sure that your application is not exposed to attacks by malicious users. -~~~~~~~ -modelClass -~~~~~~~ - property is set before any model properties are set, it's possible to choose model implementation during +While this interceptor is being invoked, a flag (`ReflectionContextState#CREATE_NULL_OBJECTS`) is turned on to ensure +that any null reference is automatically created - if possible. See the type conversion documentation +and the `InstantiatingNullHandler` javadocs for more information. -~~~~~~~ -action.setModelClass() -~~~~~~~ - call\. Similarly it's possible to use +Finally, a third flag (`XWorkConverter#REPORT_CONVERSION_ERRORS`) is set that indicates any errors when converting +the values to their final data type (`String[] -> int`) an unrecoverable error occurred. With this flag set, the type +conversion errors will be reported in the action context. See the type conversion documentation and the `XWorkConverter` +javadocs for more information. -~~~~~~~ -action.setPrimaryKey() -~~~~~~~ -property set call to actually load the model class from persistent storage\. Without any assumption on parameter order you have to use patterns like _Preparable Interface_ \. +If you are looking for detailed logging information about your parameters, turn on `DEBUG` level logging for this +interceptor. A detailed log of all the parameter keys and values will be reported. -Because parameter names are effectively OGNL statements, it is important that security be taken in to account\. This interceptor will not apply any values in the parameters map if the expression contains an assignment (=), multiple expressions (,), or references any objects in the context (\#)\. This is all done in the +Since XWork 2.0.2, this interceptor extends `MethodFilterInterceptor`, therefore being able to deal with +excludeMethods/includeMethods parameters. See [Default Workflow Interceptor](default-workflow-interceptor.html) +for documentation and examples on how to use this feature. -~~~~~~~ -#acceptableName(String) -~~~~~~~ - method\. In addition to this method, if the action being invoked implements the +For more information on ways to restrict the parameter names allowed, see the `ParameterNameAware` javadocs. -~~~~~~~ -ParameterNameAware -~~~~~~~ - interface, the action will be consulted to determine if the parameter should be set\. -In addition to these restrictions, a flag ( +## Parameters -~~~~~~~ -ReflectionContextState#DENY_METHOD_EXECUTION -~~~~~~~ - ) is set such that no methods are allowed to be invoked\. That means that any expression such as +- `ordered` - set to true if you want the top-down property setter behaviour +- `acceptParamNames` - a comma delimited list of regular expressions to describe a whitelist of accepted parameter names. + Don't change the default unless you know what you are doing in terms of security implications +- `excludeParams` - a comma delimited list of regular expressions to describe a blacklist of not allowed parameter names +- `paramNameMaxLength` - the maximum length of parameter names; parameters with longer names will be ignored; + the default is 100 characters -~~~~~~~ -person.doSomething() -~~~~~~~ - or +## Excluding parameters -~~~~~~~ -person.getName() -~~~~~~~ - will be explicitly forbidden\. This is needed to make sure that your application is not exposed to attacks by malicious users\. - -While this interceptor is being invoked, a flag ( - -~~~~~~~ -ReflectionContextState#CREATE_NULL_OBJECTS -~~~~~~~ - ) is turned on to ensure that any null reference is automatically created \- if possible\. See the type conversion documentation and the - -~~~~~~~ -InstantiatingNullHandler -~~~~~~~ - javadocs for more information\. - -Finally, a third flag ( - -~~~~~~~ -XWorkConverter#REPORT_CONVERSION_ERRORS -~~~~~~~ - ) is set that indicates any errors when converting the the values to their final data type (String\[\] \-> int) an unrecoverable error occurred\. With this flag set, the type conversion errors will be reported in the action context\. See the type conversion documentation and the - -~~~~~~~ -XWorkConverter -~~~~~~~ - javadocs for more information\. - -If you are looking for detailed logging information about your parameters, turn on - -~~~~~~~ -DEBUG -~~~~~~~ - level logging for this interceptor\. A detailed log of all the parameter keys and values will be reported\. - - - -Since XWork 2\.0\.2, this interceptor extends MethodFilterInterceptor, therefore being able to deal with excludeMethods / includeMethods parameters\. See [Default Workflow Interceptor](default-workflow-interceptor.html) for documentation and examples on how to use this feature\. - -| - -For more information on ways to restrict the parameter names allowed, see the - -~~~~~~~ -ParameterNameAware -~~~~~~~ - javadocs\. - -#####Parameters##### - -+ - -~~~~~~~ -ordered -~~~~~~~ - \- set to true if you want the top\-down property setter behaviour - -+ - -~~~~~~~ -acceptParamNames -~~~~~~~ - \- a comma delimited list of regular expressions to describe a whitelist of accepted parameter names\. Don't change the default unless you know what you are doing in terms of security implications - -+ - -~~~~~~~ -excludeParams -~~~~~~~ - \- a comma delimited list of regular expressions to describe a blacklist of not allowed parameter names - -+ - -~~~~~~~ -paramNameMaxLength -~~~~~~~ - \- the maximum length of parameter names; parameters with longer names will be ignored; the default is 100 characters - -#####Excluding parameters##### - -This interceptor can be forced to ignore parameters, by setting its _excludeParams_ attribute\. This attribute accepts a comma separated list of regular expressions\. When any of these expressions match the name of a parameter, such parameter will be ignored by the interceptor\. Interceptor stacks defined by Struts already exclude some parameters: +This interceptor can be forced to ignore parameters, by setting its `excludeParams` attribute. This attribute accepts +a comma separated list of regular expressions. When any of these expressions match the name of a parameter, such parameter +will be ignored by the interceptor. Interceptor stacks defined by Struts already exclude some parameters: **Default List of Parameters Excluded** +``` +dojo..*,^struts..*,^session..*,^request..*,^application..*,^servlet(Request|Response)..*,parameters...* +``` -~~~~~~~ -dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...* - -~~~~~~~ - -Below is an example of adding a parameter named submit to the list of parameters that should be excluded\. +Below is an example of adding a parameter named submit to the list of parameters that should be excluded. **Setup Interceptor Stack To Exclude submit Parameter** - -~~~~~~~ +```xml <interceptors> <interceptor-stack name="appDefault"> <interceptor-ref name="defaultStack"> <param name="exception.logEnabled">true</param> <param name="exception.logLevel">ERROR</param> - <param name="params.excludeParams">dojo\..*,^struts\..*,^session\..*,^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*,submit</param> + <param name="params.excludeParams">dojo..*,^struts..*,^session..*,^request..*,^application..*,^servlet(Request|Response)..*,parameters...*,submit</param> </interceptor-ref> </interceptor-stack> </interceptors> - -<default-interceptor-ref name="appDefault" /> - -~~~~~~~ - -#####Extending the Interceptor##### - -The best way to add behavior to this interceptor is to utilize the -~~~~~~~ -ParameterNameAware -~~~~~~~ - interface in your actions\. However, if you wish to apply a global rule that isn't implemented in your action, then you could extend this interceptor and override the - -~~~~~~~ -#acceptableName(String) -~~~~~~~ - method\. - - -> - -> - -> Using ParameterNameAware could be dangerous as ParameterNameAware\#acceptableParameterName(String) takes precedence over ParametersInterceptor which means if ParametersInterceptor excluded given parameter name you can accept it with ParameterNameAware\#acceptableParameterName(String)\. +<default-interceptor-ref name="appDefault" /> +``` -> +## Extending the Interceptor -> +The best way to add behavior to this interceptor is to utilize the `ParameterNameAware` interface in your actions. +However, if you wish to apply a global rule that isn't implemented in your action, then you could extend this interceptor +and override the `#acceptableName(String)` method. -> The best idea is to define very tight restrictions with ParametersInterceptor and relax them per action with ParameterNameAware\#acceptableParameterName(String) +> Using `ParameterNameAware` could be dangerous as `ParameterNameAware#acceptableParameterName(String)` takes precedence +> over `ParametersInterceptor` which means if `ParametersInterceptor` excluded given parameter name you can accept +> it with `ParameterNameAware#acceptableParameterName(String)`. -> +> The best idea is to define very tight restrictions with `ParametersInterceptor` and relax them per action +> with `ParameterNameAware#acceptableParameterName(String)` -#####Warning on missing parameters##### +## Warning on missing parameters When there is no setter for given parameter name, a warning message like below will be logged in devMode: - -~~~~~~~ +``` SEVERE: Developer Notification (set struts.devMode to false to disable this message): Unexpected Exception caught setting 'search' on 'class demo.ItemSearchAction: Error setting expression 'search' with value ['search', ] Error setting expression 'search' with value ['search', ] - [unknown location] - at com.opensymphony.xwork2.ognl.OgnlValueStack.handleRuntimeException(OgnlValueStack.java:201) - at com.opensymphony.xwork2.ognl.OgnlValueStack.setValue(OgnlValueStack.java:178) - at com.opensymphony.xwork2.ognl.OgnlValueStack.setParameter(OgnlValueStack.java:152) - -~~~~~~~ - -Thus is expected behaviour to allow developer to spot missing setter or typo in either parameter name or setter\. - -#####Examples##### + at com.opensymphony.xwork2.ognl.OgnlValueStack.handleRuntimeException(OgnlValueStack.java:201) + at com.opensymphony.xwork2.ognl.OgnlValueStack.setValue(OgnlValueStack.java:178) + at com.opensymphony.xwork2.ognl.OgnlValueStack.setParameter(OgnlValueStack.java:152) +``` +Thus is expected behaviour to allow developer to spot missing setter or typo in either parameter name or setter. +###Examples -~~~~~~~ +```xml <action name="someAction" class="com.examples.SomeAction"> <interceptor-ref name="params"/> <result name="success">good_result.ftl</result> </action> -~~~~~~~ +``` http://git-wip-us.apache.org/repos/asf/struts-site/blob/b4f6a844/source/core-developers/pre-result-listener.md ---------------------------------------------------------------------- diff --git a/source/core-developers/pre-result-listener.md b/source/core-developers/pre-result-listener.md index 44d106c..5303bc8 100644 --- a/source/core-developers/pre-result-listener.md +++ b/source/core-developers/pre-result-listener.md @@ -5,18 +5,17 @@ title: PreResultListener # PreResultListener -A PreResultListener can affect an action invocation between the interceptor/action phase and the result phase\. Typical uses include switching to a different Result or somehow modifying the Result or Action objects before the Result executes\. +A `PreResultListener` can affect an action invocation between the interceptor/action phase and the result phase. +Typical uses include switching to a different Result or somehow modifying the Result or Action objects before +the Result executes. -####Examples#### +## Examples -A PreResultListener can be added by an Action or an Interceptor\. +A `PreResultListener` can be added by an Action or an Interceptor. -#####By an Action##### - - - -~~~~~~~ +### By an Action +```java public class MyAction extends ActionSupport { ... public String execute() throws Exception { @@ -30,15 +29,11 @@ A PreResultListener can be added by an Action or an Interceptor\. } ... } +``` -~~~~~~~ - -#####By an Interceptor##### - - - -~~~~~~~ +### By an Interceptor +```java public class MyInterceptor extends AbstractInterceptor { ... public String intercept(ActionInvocation invocation) throws Exception { @@ -51,5 +46,4 @@ A PreResultListener can be added by an Action or an Interceptor\. } ... } - -~~~~~~~ +``` http://git-wip-us.apache.org/repos/asf/struts-site/blob/b4f6a844/source/core-developers/result-types.md ---------------------------------------------------------------------- diff --git a/source/core-developers/result-types.md b/source/core-developers/result-types.md index 08880ff..7cab0a5 100644 --- a/source/core-developers/result-types.md +++ b/source/core-developers/result-types.md @@ -5,19 +5,16 @@ title: Result Types # Result Types -Most use cases can be divided into two phases\. First, we need to change or query the application's state, and then we need to present an updated view of the application\. The Action class manages the application's state, and the Result Type manages the view\. +Most use cases can be divided into two phases. First, we need to change or query the application's state, and then we need +to present an updated view of the application. The Action class manages the application's state, and the Result Type +manages the view. -####Predefined Result Types#### +## Predefined Result Types -The framework provides several implementations of the - -~~~~~~~ -com.opensymphony.xwork2.Result -~~~~~~~ - interface, ready to use in your own applications\. +The framework provides several implementations of the `com.opensymphony.xwork2.Result` interface, ready to use in your +own applications. |[Chain Result](chain-result.html)|Used for [Action Chaining](action-chaining.html)| -|---------------------------|---------------------------------------| |[Dispatcher Result](dispatcher-reult.html)|Used for web resource integration, including _JSP_ integration| |[FreeMarker Result](freemarker-result.html)|Used for _FreeMarker_ integration| |[HttpHeader Result](httpheader-result.html)|Used to control special HTTP behaviors| @@ -26,73 +23,56 @@ com.opensymphony.xwork2.Result |[Stream Result](stream-result.html)|Used to stream an InputStream back to the browser (usually for file downloads)| |[Velocity Result](velocity-result.html)|Used for _Velocity_ integration| |[XSL Result](xsl-result.html)|Used for XML/XSLT integration| -|[PlainText Result](plaintext-result.html)|Used to display the raw content of a particular page (i\.e jsp, HTML)| -|_Tiles 2 Result_ |Used to provide Tiles 2 integration| -|_Tiles 3 Result_ |Used to provide Tiles 3 integration| +|[PlainText Result](plaintext-result.html)|Used to display the raw content of a particular page (i.e jsp, HTML)| +|[Tiles Result](tiles-result.html)|Used to provide Tiles integration| |[Postback Result](postback-result.html)|Used to postback request parameters as a form to the specified destination| -|_JSON Result_ |Used to serialize actions into JSON| - -#####Optional##### - -|_JasperReports Plugin_ |Used for _JasperReports Tutorial_ integration|Optional, third\-party plugin| -|-----------------------|----------------------------------------------|-----------------------------| +|[JSON Result](json-result.html) |Used to serialize actions into JSON| -Additional Result Types can be created and plugged into an application by implementing the +## Optional -~~~~~~~ -com.opensymphony.xwork2.Result -~~~~~~~ - interface\. Custom Result Types might include generating an email or JMS message, generating images, and so forth\. +|[JasperReports Plugin]|Used for _JasperReports Tutorial_ integration|Optional, third-party plugin| -####Default Parameters#### +Additional Result Types can be created and plugged into an application by implementing the `com.opensymphony.xwork2.Result` +interface. Custom Result Types might include generating an email or JMS message, generating images, and so forth. -To minimize configuration, Results can be configured with a single value, which will be converted into a parameter, and each Result can specify which parameter this value should be set as\. For example, here is a result defined in XML that uses a default parameter: +## Default Parameters +To minimize configuration, Results can be configured with a single value, which will be converted into a parameter, +and each Result can specify which parameter this value should be set as. For example, here is a result defined in XML +that uses a default parameter: -~~~~~~~ +```xml <result type="freemarker">foo.fm</result> - -~~~~~~~ +``` That is the equivalent to this: - -~~~~~~~ +```xml <result type="freemarker"> <param name="location">foo.vm</param> </result> +``` -~~~~~~~ - -Since probably 95% of your actions won't need results that contain multiple parameters, this little shortcut saves you a significant amount of configuration\. It also follows that if you have specified the default parameter, you don't need to set the same parameter as a specifically\-named parameter\. +Since probably 95% of your actions won't need results that contain multiple parameters, this little shortcut saves you +a significant amount of configuration. It also follows that if you have specified the default parameter, you don't need +to set the same parameter as a specifically-named parameter. -####Registering Result Types#### +## Registering Result Types All Result Types are plugged in via the [Result Configuration](result-configuration.html). -#####Extending##### +## Extending -You can always extend defined result types and implement whatever logic you need\. To simplify process of that, you can define your custom - -~~~~~~~ -ResultFactory -~~~~~~~ - and use it with connection with custom interface which your Result implements\. Check [Define dedicated factory](object-factory.html) to see how to do it\. +You can always extend defined result types and implement whatever logic you need. To simplify process of that, you can +define your custom `ResultFactory` and use it with connection with custom interface which your Result implements. +Check [Define dedicated factory](object-factory.html) to see how to do it. Struts 2 provides one such extension for you: -~~~~~~~ -ParamNameAwareResult -~~~~~~~ - interface when used with - -~~~~~~~ -StrutsResultBuilder -~~~~~~~ - can limit parameters assigned to the result\. So you can simple extend existing result with such a functionality as below: - +`ParamNameAwareResult` interface when used with `StrutsResultBuilder` can limit parameters assigned to the result. +So you can simple extend existing result with such a functionality as below: -~~~~~~~ +```java public class MyResult extends ServletDispatcherResult implements ParamNameAwareResult { public boolean acceptableParamName(String name, String value) { @@ -100,12 +80,6 @@ public class MyResult extends ServletDispatcherResult implements ParamNameAwareR } } +``` -~~~~~~~ - -and then register it and use instead of default - -~~~~~~~ -dispatcher -~~~~~~~ - result\. \ No newline at end of file +and then register it and use instead of default `dispatcher` result. http://git-wip-us.apache.org/repos/asf/struts-site/blob/b4f6a844/source/core-developers/static-content.md ---------------------------------------------------------------------- diff --git a/source/core-developers/static-content.md b/source/core-developers/static-content.md index 4d1ad28..a0fd563 100644 --- a/source/core-developers/static-content.md +++ b/source/core-developers/static-content.md @@ -5,89 +5,49 @@ title: Static Content # Static Content -Struts can serve static content like css and javascript files\. This feature is enabled by default, but can be disabled by setting: - - -~~~~~~~ +Struts can serve static content like css and javascript files. This feature is enabled by default, but can be disabled +by setting: +```xml <constant name="struts.serve.static" value="false" /> +``` -~~~~~~~ - - -> - -> - -> If you disable this feature, but use the xhtml, or css\_xhtml theme, make sure that the javascript and css files shipped inside the core jar are extracted to your web application directory\. - -> - -#####Custom Static Content Loaders##### - -Static content is served by an implementation of - -~~~~~~~ -org.apache.struts2.dispatcher.StaticContentLoader -~~~~~~~ -\. To write your own - -~~~~~~~ -StaticContentLoader -~~~~~~~ -, implement +> If you disable this feature, but use the `xhtml`, or `css_xhtml` theme, make sure that the javascript and css files +> shipped inside the core jar are extracted to your web application directory. -~~~~~~~ -StaticContentLoader -~~~~~~~ - and define a bean for the class: +## Custom Static Content Loaders +Static content is served by an implementation of `org.apache.struts2.dispatcher.StaticContentLoader`. To write your own +`StaticContentLoader`, implement `StaticContentLoader` and define a bean for the class: -~~~~~~~ - +```xml <bean type="org.apache.struts2.dispatcher.StaticContentLoader" class="MyStaticContentLoader" name="myLoader" /> <constant name="struts.staticContentLoader" value="myLoader" /> +``` -~~~~~~~ - -#####Default Content Loader##### - -Struts provides a default implementation of - -~~~~~~~ -StaticContentLoader -~~~~~~~ - which is - -~~~~~~~ -org.apache.struts2.dispatcher.DefaultStaticContentLoader -~~~~~~~ -\. This loader will handle urls that start with "/static/"\. - -This content loader can serve static content from the classpath, so when writing a plugin, you can put a file inside your plugin's jar like "/static/image/banner\.jpg" and it will be served when the url "/static/image/banner\.jpg" is requested\. +## Default Content Loader +Struts provides a default implementation of `StaticContentLoader` which is `org.apache.struts2.dispatcher.DefaultStaticContentLoader`. +This loader will handle urls that start with "/static/". +This content loader can serve static content from the classpath, so when writing a plugin, you can put a file inside +your plugin's jar like "/static/image/banner.jpg" and it will be served when the url "/static/image/banner.jpg" is +requested. -| This loader is not optimized to handle static content, and to improve performance, it is recommended that you extract your static content to the web application directory, and let the container handle them\. +> This loader is not optimized to handle static content, and to improve performance, it is recommended that you extract +> your static content to the web application directory, and let the container handle them. -| +## Preventing Struts from Handling a Request -#####Preventing Struts from Handling a Request##### - -If there is a request that Struts is handling as an action, and you wish to make Struts ignore it, you can do so by specifying a comma separated list of regular expressions like: - - -~~~~~~~ +If there is a request that Struts is handling as an action, and you wish to make Struts ignore it, you can do so by specifying +a comma separated list of regular expressions like: +```xml <constant name="struts.action.excludePattern" value="/some/conent/.*?" /> +``` -~~~~~~~ - -These regular expression will be evaluated against the request's URI ( - -~~~~~~~ -HttpServletRequest.getRequestURI() -~~~~~~~ -), and if any of them matches, then Struts will not handle the request\. +These regular expression will be evaluated against the request's URI (`HttpServletRequest.getRequestURI()`), and if any +of them matches, then Struts will not handle the request. -To evaluate each pattern Pattern class from JDK will be used, you can find more about what kind of pattern you can use in the [Pattern class JavaDoc](http://docs\.oracle\.com/javase/1\.5\.0/docs/api/java/util/regex/Pattern\.html)^[http://docs\.oracle\.com/javase/1\.5\.0/docs/api/java/util/regex/Pattern\.html]\. +To evaluate each pattern Pattern class from JDK will be used, you can find more about what kind of pattern you can use +in the [Pattern class JavaDoc](http://docs.oracle.com/javase/1.5.0/docs/api/java/util/regex/Pattern.html).
