【问题标题】:Repopulating a list from JSP to action in Struts 2将列表从 JSP 重新填充到 Struts 2 中的操作
【发布时间】:2014-03-30 19:50:00
【问题描述】:

我正在使用 Struts 2 框架,我想将对象列表从 Java 传输到 JSP 并返回到 Java。使用<s:iterator> 标记传输到JSP 可以正常工作。转移回 Java 没有,我的列表永远不会填充。

我已经检查了这些问题:

并听从了他们的建议。

这是我的“项目”类(它的属性不仅仅是名称,但我只显示相关的):

类项目:

    private String name;

    public Item(){}

    public String getName(){ ... };
    public void setName(String newName){ ... };

在我的 JSP 上我有:

<s:iterator value="items" status="key">
    <s:hidden name="items[%{#key.index}].name" value="%{name}" />
</s:iterator>

下面是动作类的相关部分:

private  List<Item> items = new ArrayList<Item>();

public List<Item> getItems()
{
    System.out.println("now getting Items");
    
    if(Items == null)
    {
        System.out.println("Items is null");
    }
    else
    {
        System.out.println("Items is not null. size: " + Items.size());
    }
    
    return Items;
}

public void setItems(List<Item> Items)
{
    System.out.println("now setting Items");

    Items = Items;
}

我 100% 确定它具有所有必要的 getter 和 setter,因为 JSP 已正确填充,当我提交表单时,我实际上可以看到(使用日志语句)我的 getItems() 方法被调用一次我列表中的每个项目(对于表单中的每个输入字段)。奇怪的是,Struts2 为表单中的每个隐藏输入字段获取一次列表,但随后拒绝创建 Item 对象并将其名称设置为给定值。问题不可能是缺少无参数构造函数。

我还添加了一个名为 ActionName-conversion.properties 的转换文件(其中 ActionName 是我的操作类的名称),它与我的 ActionName.java 类位于同一文件夹中。

Element_items = Item
CreateIfNull_items = true

可能出了什么问题?

【问题讨论】:

  • 你的代码很好,你也清除了我的第一个想法(The problem cannot be the lack of a no-args constructor)。剩下什么 ?拦截器堆栈。请出示一下,我敢打赌问题出在啤酒上
  • 我使用默认堆栈(具有参数拦截器)。我刚刚测试了是否可以从我的 JSP(而不是 List)中填充一个 list,这很好用。我真的认为struts2试图创建一个新项目有问题(或者不知何故不知道列表是Item类型,因此不知道它必须创建一个项目对象?)。
  • 尝试删除您的 ActionName-conversion.properties(此处不需要),如果它不起作用,请在您的 Action 类中发布 List 的声明和初始化。
  • 删除属性文件并没有改变任何东西。我在问题中添加了动作类中的相关部分(制作、获取和设置项目列表)。你会看到 get 方法有 system.outs。实际上,我在控制台中打印了 4 次这些打印语句,并且我的项目列表有 4 个值。项目列表不为空。但是列表中元素的数量始终保持为 0。它不是只读列表或类似的东西。
  • 我猜Items 总是items,不是吗?

标签: java jsp struts2 type-conversion ognl


【解决方案1】:

如果您使用ListMap 作为您的项目集合,您可以通过索引引用其元素,而无需使用ObjectTypeDeterminer。见

Built in Type Conversion Support

类型转换由 XWork 实现。

XWork 将自动处理最常见的类型转换 你。这包括支持为每个字符串转换为字符串和从字符串转换为字符串 以下内容:

  • 字符串
  • 布尔值/布尔值
  • 字符/字符
  • int / Integer、float / Float、long / Long、double / Double
  • 日期 - 使用与当前请求关联的区域设置的 SHORT 格式
  • 数组 - 假设单个字符串可以转换为单个项目
  • 集合 - 如果不能确定对象类型,则假定它是一个字符串并创建一个新的 ArrayList

请注意,对于数组,类型转换将取决于 数组元素并尝试单独转换每个项目。与 任何其他类型的转换,如果不能执行转换 标准类型转换错误报告用于指示问题 在处理类型转换时发生。

  • 枚举
  • BigDecimal 和 BigInteger

如果您想使用高级类型转换使用ObjectTypeDeterminer 来确定填充集合时实例化的对象类型或通过OGNL 表达式中元素的key 属性从集合中检索到的对象,您应该看到

Collection and Map Support

Collection 和 Map 支持提供智能的 null 处理和类型 Java 集合的转换。

框架支持发现元素对象类型的方法 在一个集合中。发现是通过ObjectTypeDeterminer 进行的。一种 框架提供了默认实现。 Javadocs 解释如何发现 MapCollection DefaultObjectTypeDeterminer.

这个ObjectTypeDeterminer 看着Class-conversion.properties 指示地图中包含哪些对象的条目和 收藏品。对于集合,例如列表,指定元素 使用模式Element_xxx,其中xxx 是 您的操作或对象中的集合属性。对于地图,两者都是关键 并且可以使用模式Key_xxx 和指定值 分别为Element_xxx

从 WebWork 2.1.x 开始,Collection_xxx 格式仍受支持,并且 很荣幸,尽管它已弃用并且最终会被删除。

此外,您可以通过以下方式创建自己的自定义ObjectTypeDeterminer 实现ObjectTypeDeterminer 接口。还有一个 可选的ObjectTypeDeterminer,它利用 Java 5 泛型。见 Annotations 页面了解更多信息。


您可以使用ActionClass-conversion.properties 并指定类型转换所需的所有属性。如果您未指定某些属性,则会应用默认值。

在您的情况下,您没有指定关键属性,即KeyProperty_items,在这种情况下使用Itemid 属性。如果您没有此类属性,则转换可能会失败。

也可以使用注解进行类型转换。查看示例

还要注意使用 OGNL 表达式对字段名称使用正确的语法,该表达式使用对象引用进行索引,而不是通过集合索引进行引用。这种索引非常适合列表。它还可以使用高级类型转换。

为什么它的工作是这个问题的主题。当然,您可以修复您的属性并使用高级类型转换,或者删除它并使用索引集合(如列表)。

【讨论】:

    猜你喜欢
    • 2013-03-17
    • 2012-05-17
    • 1970-01-01
    • 2016-07-13
    • 2013-05-07
    • 2013-06-11
    • 1970-01-01
    • 2012-06-04
    • 2012-09-26
    相关资源
    最近更新 更多