About the Struts 2 Wiki Space

The Vault contains lots of unsorted problems, snippets, remarks and ideas, mostly found in posts in the mailing lists. You can think of this page as a place to store content before it is analyzed and put in a Tutorial, Guide, or FAQ. Material in the Wiki is raw, unpolished, and can contain typos. If you can't find it elsewhere, be sure to rummage through the Vault and search the forum.
(lightbulb) Feel free to redraft material in this space! (That's why it's here!)

Visit Stuts 2 Documentation for the official project documentation



Best practices

Should I make an action or rather link to a .jsp page ?

If you put an action configuration in your xwork.xml but don't put an action class attribute, it will default to using the ActionSupport class, which just returns SUCCESS.

Sample applications with Java 1.4.x

Struts 2 requires Java 5. However, an alternate set of jars for Java 1.4.x are available.

Steps to get Struts2 sample applications to work with java 1.4.x:

Type conversion

Type conversion for a static inner class ?

Collection_inner property name = your.package.ClassName$StaticInnerClassName (notice the dollar sign between the fully qualified Class name and the static inner class)

Freemarker, Velocity, JSP

How to disable Velocity template caching

The "wwclass" was the resource loader I need to change.
Here's the lines from Velocity.props:

wwfile.resource.loader.cache=false
wwclass.resource.loader.cache=false

(http://jroller.com/page/gigix?entry=velocity_performance_issue_solved)

How to catch Freemarker exceptions (the ugly big yellow pages)

FreeMarker delegates exception handling to so-called TemplateExceptionHandlers. By default the HTML_DEBUG_HANDLER is used (this one generates the yellow error page), but you can easily specify a different exception handler by using the setTemplateExceptionHandler method of your configuration object. FM provides some simple handlers you can use, in your case I recommend the RETHROW_HANDLER (
http://freemarker.org/docs/api/freemarker/template/TemplateExceptionHandler.html).

My s:include actions aren't processed

Did you declare the s tag library in your includes ? If I'm not mistaken, jsp includes work different from struts tags includes (struts tags process the pages before including them).

I'm using s:urlHelper in combination with the c:out tag, but it won't work !

if the url with &amp is used in the value attribute it will not work properly unless the escapeXml is set to false.

Why aren't my get parameters being propagated automatically under Websphere 5.1?

The symptoms of this issue are that when using the s:url tag, the get parameters won't be inlcuded when the includedParams attribute is set to 'get' under Websphere 5.1. (Websphere 6.1 is not affected by this issue) This issue occurs because Websphere 5.1 doesn't follow correct behavior regarding the request query string. To allow struts to work properly with Websphere 5.1, you must include the following interceptor in your interceptor stack:

package example;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.StrutsStatics;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;

/**
 * Since websphere 5.1 doesn't retain the query string past a forward, this
 * interceptor populates the 2.4 query string servlet attribute.
 */
public class Websphere51QueryStringInterceptor implements Interceptor
{
  /** Servlet 2.4 location of the query string after a forward. */
  public static final String FORWARD_QUERY_STRING_ATTRIBUTE = "javax.servlet.forward.query_string";

  /**
   * @see com.opensymphony.xwork.interceptor.Interceptor#init()
   */
  public void init()
  {
  }

  /**
   * @see com.opensymphony.xwork2.interceptor.Interceptor#intercept(com.opensymphony.xwork2.ActionInvocation)
   */
  public String intercept(ActionInvocation invocation) throws Exception
  {
    HttpServletRequest request = (HttpServletRequest) invocation
      .getInvocationContext().get(StrutsStatics.HTTP_REQUEST);
    String queryString = request.getQueryString();
    if (queryString != null)
    {
      if (request.getAttribute(FORWARD_QUERY_STRING_ATTRIBUTE) == null)
      {
        request.setAttribute(FORWARD_QUERY_STRING_ATTRIBUTE, queryString);
      }
    }
    return invocation.invoke();
  }

  /**
   * @see com.opensymphony.xwork.interceptor.Interceptor#destroy()
   */
  public void destroy()
  {
  }
}

This interceptor will grab the query string from the request before the forward occurs and put it under the query string servlet attribute as defined in the 2.4 servlet spec. This interceptor should have no affect on other servlet containers.

See https://issues.apache.org/struts/browse/WW-1563 for more details.

Validation

How to disable validation on the first page load (to show a in input form)?

If you define your own stack you can exclude methods from validation by adding the excludeMethods param to both Validation and Workflow. Assuming you are using the defaultStack the the methods input, back and cancel will be ignored. Change default to action!input and declare the input method to return INPUT.

How to disable validation on any given method?

use 

@SkipValidation tag on the method.

 

ex:

 @SkipValidation
public String logout() {...} 

 When using clientside validation, DWR states it gets No Data From Server

When using firefox if a user has focus on an input control and then clicks the submit button i get a DWR error stating that there was no data from the server.
I searched around on this group and did not see a solution. Via the DWR mailing list I found a post fromi Joe Walker stating that a workaround was to register a custom DWR error handler ..
http://getahead.ltd.uk/dwr/browser/engine/errors

Why can't I use && (=and) in my validation rules ? || (=or) does work !

You can't use && directly since the validation files have to be wellformed xml. The correct syntax would be &amp ;&amp ; (without the spaces)

Validation on individual methods

To use validation on a specific method in an action you need to call your validation file

ActionClassName-ActionName-validation.xml

Where ActionName is the value matching the name attribute of the action in the action config. Wildcard methods treats / (slashes) as - (dashes). Here is an example, if we wanted to validate only the method dir/myMethod: -

<action name="dir/*" class="com.actions.MyAction" method="{1}">
...

We would call the validation file MyAction-dir-myMethod-validation.xml. This is because ActionClassName is MyAction and ActionName is dir/myMethod, but the / is mapped to - so it becomes dir-myMethod.

Ajax, Javascript

Datepicker i18n problems

DatePicker might have some problems in certain localised enviroments, because some of the language files included in DHTML / JavaScript Calendar are not valid (don't have some variables, for example WEEKEND definition).

Is simple solution to overide files like:
http://localhost:8080/showcase/webwork/jscalendar/lang/calendar-(your language).js

The only way to fix that, is correct calendar-(your language).js...

Already fixed for 2.2.1, available via CVS HEAD:

  • sv
  • pl
  • cn

Datepicker does not allow time editing, or works with wrong date format

The trick is to format the date correctly before sending it to the datepicker, AND telling the datepicker what format you are using.

<ww:date name="%{new java.util.Date()}" format="dd-MM-yyyy hh:mm" id="date"/>
<ww:datepicker value="%{#date}" showstime="%{true}" format="%d-%m-%Y %H:%M"/>

Note: of course you should use property keys here, but you'll have to specify different keys, since the formatting expression for java and javascript are different (but should result in the same format !):

my.java.datetime.format=dd-MM-yyyy hh:mm
my.javascript.datetime.format=%d-%m-%Y %H:%M

And the use the following snippet instead:

<ww:date name="%{new java.util.Date()}" format="%{getText('my.java.datetime.format')}" id="date"/>
<ww:datepicker value="%{#date}" showstime="%{true}" format="%{getText('my.javascript.datetime.format')}"/>

Improving Dojo Performance

In Struts 2 Dojo is configured with a small dojo.js file that load other javascript resources only as required. Slow page-loads can be experienced when using the Struts 2 ajax theme as Dojo sequentially issues the series of resource requests. Performance may be significantly improved by creating a custom Dojo profile that bundles more resources directly into dojo.js.

Creating a custom Dojo profile for Struts 2.0.x

More Struts 1 -> 2 migration tips

Nested and indexed properties without the nestedTag

Living without the nestedTag in Struts2

Application servers

S2 hot-redeployment problem with Tomcat 5.5

Try to adjust your Tomcat context settings...

<Context docBase="${catalina.home}/webapps/YOURWEBAPP"
         antiResourceLocking="true" antiJARLocking="true">
...
</Context>

Deploying Struts/WebWork on Glassfish

One of my co-workers was deploying a forum application that uses WebWork code. He ran into some deployment and execution issues, related to the sercurity policy. If you want to deploy WebWork apps on GlassFish, you may want to read http://blogs.sun.com/roller/page/paulsen?entry=configuring_the_security_manager_in

Browser

Different version of a browser co-existing together

Integration

Spring Security

Spring Security (formerly Acegi Security System) is Spring's Authentication & Authorisation framework.

The following sections describe how to integrate Spring Security in Struts 2 applications.

Examples of Spring Security related set up are also provided, but they're just meant as a quick start guide. For compreehensive Spring Security documentation, please refer to the Spring Security Reference Documentation.

Spring Framework integration

Before using Spring Security, the Struts 2 application should be integrated with the Spring framework by means of the Spring Plugin. Please refer to the documentation of this plugin for information on how to use it.

Required libraries

Add the following Spring Security JAR files to the application:

  • spring-security-core-2.0.4.jar
  • spring-security-core-tiger-2.0.4.jar

Changes in web.xml

Add applicationContext-security.xml to Spring's contextConfigLocation:

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>
    /WEB-INF/applicationContext.xml
    /WEB-INF/applicationContext-security.xml
  </param-value>
</context-param>

Declare the following filter and filter mapping:

<filter>
  <filter-name>springSecurityFilterChain</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
  <filter-name>springSecurityFilterChain</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

If restrictions are to be applied to the number of concurrent sessions per user, declare the following listener:

<listener>
  <listener-class>org.springframework.security.ui.session.HttpSessionEventPublisher</listener-class>
</listener>

WEB-INF/applicationContext-security.xml

Declare mappings between URLs and required roles:

<http>
<intercept-url pattern="/**" access="ROLE_USER" />
  <intercept-url pattern="/login*" filters="none" />	<!-- login page should be public -->
  <intercept-url pattern="/admin*" access="ROLE_ADMIN" />
  <intercept-url pattern="/**" access="ROLE_USER" />
  <form-login />
  <anonymous />
  <http-basic />
  <logout />
  <remember-me />
  <!-- allow one session per user only: requires HttpSessionEventPublisher declared in web.xml -->
  <concurrent-session-control max-sessions="1" exception-if-maximum-exceeded="true" />
</http>

Declare an authentication provider. Below is an example of an in-memory authentication where two users with different sets of roles are defined:

<authentication-provider>
  <user-service>
    <user name="admin" password="admin" authorities="ROLE_USER, ROLE_ADMIN" />
    <user name="user" password="user" authorities="ROLE_USER" />
  </user-service>
</authentication-provider>

Alternatively, an authentication provider using JDBC could be declared:

<authentication-provider>
	<jdbc-user-service data-source-ref="dataSource" />	<!-- dataSource defined in applicationContext.xml -->
</authentication-provider>
  • No labels

1 Comment

  1. You can run IE4, IE5, IE6 and IE7* (with IE6 UI) on GNU/Linux with IEs4Linux: http://www.tatanka.com.br/ies4linux/page/Main_Page