对于包含这些成员变量的简单动作类:
...
private TestConverterEnum test;
private TestConverterEnum[] tests;
private List<TestConverterEnum> tList;
...
简单的枚举:
public enum TestConverterEnum {
A,
B,
C;
}
使用默认的struts2枚举转换,当我发送请求时:
TestConterter.action?test=&tests=&tList=&b=asdf
对于test
,我得到null
值,这是预期的。但是,对于Array和List,我得到一个带有一个null元素的Array(或list)。这是预期的吗?有没有办法防止这种情况。
我们最近升级了我们的struts2版本,我们有自己的转换器,在这种情况下也不起作用,所以我希望使用默认的转换方法。我们已经有代码验证null
和长度的这些数组,我不想为这些分支添加另一个条件。有没有办法防止这种情况发生?
答案 0 :(得分:2)
是的,这是预期的行为IMO。
Http参数原则上是多值的(通常用于多值选择列表),因此struts2 param拦截器(通过反射)询问接受数组的setter或(作为第二个选项)单个值。你的动作可能有一个setTests(TestConverterEnum[] a)
setter,所以,当Struts2的拦截器必须映射tests=
时,他发现了这个setter,并且认为自己:“我必须用数组设置这个'tests'属性,让我们看看传递了多少参数...只有一个(空),然后让我们创建一个长度为1的数组并用转换填充它......“等。
我觉得合理:你的请求包含一个'tests'参数(虽然是空的),因此创建了一个一个大小的数组。
我敢打赌,如果你尝试TestConterter.action?tests=&tests=
,将会创建一个长度为2的数组。
已更新:
让我们看看我们是否同意这一点:在请求中传递一个空参数(原则上)不与不传递它相同...虽然经常有人想要将这两个案例视为等效。
如果你想告诉Struts2:“完全忽略空参数” ......我不认为(假设这是一个可以接受的想法)这种行为可以由一些全局强制执行设置。 您总是可以编写自己的拦截器(或扩展参数拦截器),以便在映射之前清除请求中的空参数。
顺便说一句,请注意,这个问题与Enums或Arrays无关,完全是一般的。现在,多值参数的情况需要额外考虑。我假设如果你的Action有一个类型为array的公共属性,那是因为它可以用几个参数设置(通常是一个SELECT MULTIPLE) - 如果没有,这里有一些设计问题。 现在,您对此请求的预期行为是什么?
TestConterter.action?tests=&tests=A&tests=&tests=B&tests=B
这是否应生成长度为5 [null, A, null, B, B]
或3 [A, B, B]
或2 [A, B]
的数组?
给出一般标准很难;这就是为什么在你的setter方法中更好地处理这个问题的原因。