7

我有一个 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;
}

我传递了一个格式如下的 URL:

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

即使 Map 具有指定为 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

4 回答 4

8

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

以下是解决该问题的一些指导方针:

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

长话短说遵循惯例。以上行为用 Struts 2.3.4 测试

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

于 2012-11-29T03:47:22.697 回答
4

你使用了错误的符号。filters.fromDate将相当于getFilters().setFromDate(),这实际上不是您想要的。点表示法适用于 JavaBeans。

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

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

于 2012-11-28T20:37:50.633 回答
0

试试这个:

 Object[] obj = (Object[]) filters.get( "fromDate" );
 String value = (String)obj[0]);
于 2012-11-28T19:14:10.280 回答
0

这不是一个错误,您可以认为它是一个功能。访问请求参数

参数感知拦截器

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

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

于 2012-11-28T19:16:42.977 回答