Why does Struts2 convert my string to an array of strings?

I have a Struts 2 application (JDK 1.7, Struts 2.2.1) that contains a list of filtering criteria stored as strings on a map.

Map< String, String > m_filters = new HashMap< String, String >(); public Map< String, String > getFilters() { return m_filters; } 

I am passing a URL formatted as follows:

http://myserver.com/myapp/GenerateReport.action?reportID=Whatever&filters.fromDate=0&filters.toDate=2000000000&filters.FcsType=piv_cardholder_3kp&detailed=true

Despite the fact that the map has both keys and value types specified as String, it tries to get the value from this

  Map< String, String > filters = getFilters(); String value = filters.get( "fromDate" ); 

throws this exception:

java.lang.ClassCastException: [Ljava.lang.String; cannot be cast to java.lang.String

I reproduced this in unit test and confirmed in the debugger that Struts 2 seems to create String [1] instead of String for each of the parameters. those. it is a string array of length 1, with the only string being the expected value ("0" in this case).

My question is: Is this a bug in Struts2, or am I doing something wrong?

If this is an error, is there a known workaround?

+7
source share
4 answers

No problem if you follow the Java bean conventions.

Below are some suggestions for resolving the issue:

  • This problem does not occur if you call the private filter "filter" and provide only the filter for the filter.
  • This problem does not occur if you provide a public setter (even if you use a different name for a private member such as m_filter) in addition to getter
  • This problem only occurs if you do not provide a setter and the property does not have the same name as the recipient.

In short, follow the conventions. Above behavior tested with Struts 2.3.4

What I suppose is happening . The getter also allows you to set (if there was only a setter, you could set only one element on the map, well, with the help of the current parameter interceptor this is the case). the bean is checked for property to see how it should convert the type, probably it looks first that the setter is not working, that it looks at the action to push that name in order to determine the type in which it will not need to use the default value , The default parameter type is the mapping of String to String [], and this is what you see.

+6
source

You are using the wrong notation. filters.fromDate will be the equivalent of getFilters().setFromDate() , which is not really what you want. The dot notation is for JavaBeans.

Try using parentheses, for example filters['fromDate'] .

Contact: http://struts.apache.org/2.2.1/docs/type-conversion.html#TypeConversion-RelationshiptoParameterNames .

+4
source

Try the following:

  Object[] obj = (Object[]) filters.get( "fromDate" ); String value = (String)obj[0]); 
0
source

This is not a mistake that you can consider its feature. Access RequestParameters

ParameterAware Interceptor

Assume /http://localhost:8080/myApp/login.action?name=struts2&name=rocks

if you try to access the name parameter string [0] = struts2, line 1 = rocks

0
source

All Articles