【问题标题】:How to use Struts 2 push tag for form input fields?如何为表单输入字段使用 Struts 2 push 标签?
【发布时间】:2014-10-09 07:21:17
【问题描述】:

我有两个类,一个是 Action 类 MyAction,另一个是 POJO 类 User。在MyAction 内部,我为User 类做了getter-setter。

然后我有index.jsp 页面供用户输入。在此,我使用 struts 2 push 标记存储在 User 类中的属性。它看起来像这样:

<s:form action="go" method="post">
    <s:push value="user">
        <s:textfield name="id" label="usr-id"/>              <!-- user.id    -->
        <s:textfield name="fname" label="first-name"/>       <!-- user.fname -->
    </s:push>
    <s:submit/>
    <s:token/>
</s:form>

但是我遇到了一个错误。如果我删除 push 标签并在 User 属性前加上 user,那么它运行良好。谁能指导我,我错在哪里以及如何在表单中的输入字段中使用push标签。

【问题讨论】:

  • 谢谢@Imran。所以根据 mkyong 的说法,我们必须首先创建 bean,然后将该 bean 引用到 push 值。您(mkyong)的解决方案很棒,但没有直接的方法吗?假设,我有一个很长的 OGNL expr,比如 user.address.city... 如何实现这一点。我知道我听起来很生气,但你能帮我在推标签中的 OGNL 长链中吗?
  • 抱歉打扰你@Imran,但谢谢。我的困惑一扫而光。祝你有美好的一天!
  • 你为什么要使用&lt;s:push&gt;标签?
  • 不值得吗?我的意思是,如果我们对同一个对象有这么多的属性,那么将那个对象推到值堆栈的顶部不是一个好习惯……而不是每次都给那个对象加上它的属性的后缀。我做错了吗?

标签: java jsp struts2 ognl struts-tags


【解决方案1】:

无论您使用&lt;s:push&gt;&lt;s:set/&gt;&lt;s:iterator&gt; 及其varIteratorStatus 属性...:

  • 显示一个值,任何方式都是好方式;
  • 发送 一个值,only 方式是在name 属性中指定完整的“路径”。

比如可以在value属性中使用push的对象,但是要让它在提交的时候生效,还是需要在name属性中放入user

<s:push value="user">
    <s:textfield name="user.id" value="id"      />       <!-- user.id    -->
    <s:textfield name="user.fname" value="fname"/>       <!-- user.fname -->
</s:push>

这使得在您的情况下使用 &lt;s:push&gt; 完全没用。

但是在源和目标不同的用例中,例如。您从 ActionSource 读取 user.fname,并将其值以 selectedFname 字符串的形式发送到 ActionDestination,jsp 将是

<s:push value="user">
    <s:textfield name="selectedId"    value="id"   />       <!-- user.id    -->
    <s:textfield name="selectedFname" value="fname"/>       <!-- user.fname -->
</s:push>

所以它会做“一些有用的事情”

但根据我的经验,您几乎不会使用 push。如果你需要它,你的数据结构可能太复杂了。

【讨论】:

  • 谢谢@Andrea。我想问一下,我可以使用push 标签和bean 标签。就像首先为具有var 属性的User 类创建一个bean,然后将其引用到push 值。这是我得到这个逻辑的链接:mkyong.com/struts2/struts-2-push-tag-example
  • 我几乎从不使用 (而且,在你问之前,)标签。这本身并不是一个坏习惯,我只是认为它是一种旧的思考编码方式。我几年前就用过,现在不用了。
  • @JSK 我看到了未来:and, before you ask, the <s:action> :D PS:如果您发现答案有用,请考虑投票。
【解决方案2】:

您的代码看起来没问题,但是要从文本字段发送值,您需要再次将 user 对象推送到堆栈。最好在 params 拦截器填充操作之前使用一些拦截器。同样的事情正在做modelDriven interceptor

模型驱动拦截器监视ModelDriven 动作并将动作的模型添加到值堆栈的top

注意:如果要将参数应用于模型,ModelDrivenInterceptor 必须位于 StaticParametersInterceptorParametersInterceptor 之前。

注意:只有当模型不是null时,ModelDrivenInterceptor才会将模型推入堆栈,否则将被忽略。

您可以使用模型驱动方法,它为视图和控制器推送模型。您的代码中缺少最后一个。

The example of using ModelDriven approach.

【讨论】:

  • 感谢@roman 在某种程度上消除了我的疑虑。是的,我用过ModelDrivenInterceptor。在这里,我只是想了解push 标签的工作原理。通过push 内的properties 标签接收数据没有问题。但是当我尝试使用相同的push 标签发送数据时出现错误。所以,根据你我的理解是:param 拦截器在我按下提交按钮时在这里触发,它(参数)再次重新初始化值堆栈。从而忽略推送的对象。我是错还是对?
  • 被推送的对象在标签末尾从堆栈中弹出,让您不高兴。提交表单还需要向服务器发出新请求,以及新的操作上下文和值堆栈。
  • push 标签与视图层上的值堆栈一起工作,它适用于当前操作上下文,但不适用于另一个操作请求,因为它运行在另一个上下文中。如果您希望模型在请求之间保持不变,请使用 scopedModelDriven 拦截器。
  • @JSK:不要使用模型驱动。事情只是在没有模型驱动和推送标签和bean标签的情况下工作。保持简单。
  • @AleksandrM 这是的方法——如果你不知道如何使用,就不要使用它。 :)
【解决方案3】:

Push 不是 ui 标签。 Push 用于将对象放入值堆栈的顶部。如果您的对象不在堆栈顶部,您可以使用object.attributname 获取您的值。如果你的对象在值栈中,可以直接attributename访问。

【讨论】:

    猜你喜欢
    • 2014-10-19
    • 1970-01-01
    • 2011-10-14
    • 1970-01-01
    • 2013-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多