为什么Struts2将我的字符串转换为字符串数组?

时间:2012-11-28 19:04:31

标签: java struts2

我有一个Struts 2(JDK 1.7,Struts 2.2.1)应用程序,它包含一个过滤条件列表,在地图中存储为字符串。

Map< String, String > m_filters = new HashMap< String, String >();

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

我传递的格式如下:

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

即使地图同时具有密钥和&amp;指定为String的值类型,尝试从此

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

导致抛出此异常:

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

我在单元测试中重现了这一点,并在调试器中确认Struts 2似乎为每个参数创建了一个String [1]而不是String。即它是一个长度为1的字符串数组,唯一的字符串是期望值(在这种情况下为“0”)。

我的问题是:这是Struts2中的错误,还是我做错了什么?

如果是错误,是否有已知的解决方法?

4 个答案:

答案 0 :(得分:8)

如果遵循Java bean约定,则没有问题。

以下是解决此问题的一些指导原则:

  • 如果您将私有成员命名为“过滤器”并仅提供过滤器的getter,则不会发生此问题。
  • 如果您提供公共设置器(即使您为私有成员使用其他名称,例如m_filter),除了getter之外,也不会发生此问题
  • 只有在您不提供setter并且该属性与getter的名称不同时才会出现此问题。

长篇短篇小说。以上行为使用Struts 2.3.4测试

我猜测正在发生什么:getter也允许设置(如果只有一个setter你只能在地图中设置一个项目,那么当前的参数拦截器就是这个案件)。检查bean的属性以查看它应该如何进行类型转换可能首先它查找一个setter失败,它查看该名称的属性的动作以确定它将需要使用默认值的类型失败。默认参数类型是String到String []的映射,这就是您所看到的。

答案 1 :(得分:4)

你使用了错误的符号。 filters.fromDate等同于getFilters().setFromDate(),实际上并不是您想要的。点符号适用于JavaBeans。

尝试使用括号,例如filters['fromDate']

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

答案 2 :(得分:0)

试试这个:

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

答案 3 :(得分:0)

这不是一个你可以认为它是一个功能的错误。 Access RequestParameters

ParameterAware Interceptor

让我们假设/http://localhost:8080/myApp/login.action?name=struts2&name=rocks

如果您尝试访问名称参数string [0] = struts2,string 1 = rocks