【问题标题】:JSF getValue() v.s. getSubmittedValue()JSF getValue() 与获取提交的值()
【发布时间】:2010-09-20 13:54:47
【问题描述】:

我最近一直在开发一些 JSF 应用程序,并且对 Web 组件 API 的不一致感到不安。

我注意到在服务器端代码中对 JSF 组件对象调用 .getValue() 或 .getSubmittedValue() 时会出现极其不可预测的行为。有时,当我在下拉列表框上调用 .getValue() 时,我注意到我得到的值是在我选择我的值之前的值(因此来自最后一页刷新的值),其中 .getSubmittedValue() 得到我是正确的值,例如:

UIInput name = new UIInput(); // This is the control I have in a bean.

public void submit(ActionEvent ae)
{
    someMethod(name.getValue().toString());          // Retrieves the "old" value
    someMethod(name.getSubmittedValue().toString()); // Retrieves the correct value 
}

另外,我注意到在表单字段上调用 ​​.getSubmittedValue() 有时会导致空指针异常,因为该值尚未在组件对象中实例化,在这种情况下,当我调用 .getValue() 时情况我得到正确的值,例如:

HtmlInputText name = new HtmlInputText(); // This is the control I have in a bean.

public void submit(ActionEvent ae)
{
    someMethod(name.getValue().toString());          // Retrieves the correct value
    someMethod(name.getSubmittedValue().toString()); // Throws NullPointerException 
}

这只是 JSF 框架的一个“怪癖”,还是我只是错误地使用了 API COMPLETELY?对这两种方法的任何见解将不胜感激。干杯。

【问题讨论】:

  • 您正在使用哪个 JSF 实现?这可能是一个具有特定风格的错误,而不是标准。
  • 我正在使用 Infragistics NetAdvantage 组件,JSF 1.2。

标签: jsf


【解决方案1】:

由于这是在 Google 中搜索 getValue 与 getSubmittedValue 的第一结果,我想补充一点,它们之间的区别在验证中至关重要(即在编写自定义验证器时)

引用 getSubmittedValue() 的 API 文档:

这仅在解码之间为非空 并验证阶段,或何时 组件的验证没有 成功了。一旦转换和 验证成功,则 (转换后的)值存储在 this 的本地“价值”属性 组件,提交的值为 重置为空。

来源:http://myfaces.apache.org/core11/myfaces-api/apidocs/javax/faces/component/UIInput.html#getSubmittedValue()

这意味着如果您尝试访问的绑定发生了验证/转换,您应该调用 getValue() 否则您将不得不调用 getSubmittedValue() 并自己处理解析它。这些发生的顺序似乎是由它们在 UI 中出现的顺序决定的,但我认为这不能保证。即使是这样,您也不应该指望这一点,因为在您的 UI 中更改字段不应该破坏您的代码。

您可以通过查看 isLocalValueSet() 返回的内容来检测验证/转换是否已完成。如果它返回 true,那么验证/转换已经完成,所以你应该调用 getValue()。否则,您将需要调用 getSubmittedValue(),这将为您提供用户输入的原始输入,您可能希望将其解析为更有意义的内容。

例如,当调用 getValue() 时,日历对象将返回 Date 对象,而在调用 getSubmittedValue() 时将返回 String 对象。由您的转换器将字符串解析为日期,以便对其进行验证。

如果 JSF 规范有一种方法可以为我们做到这一点,那就太好了,但 AFAIK 没有。如果某些日期需要在其他日期之前,而有些仅在某些情况下需要,则需要编写几个验证器来处理这个问题。所以它很容易成为一个问题。这类似于您不能对空白字段进行任何类型的验证,这意味着您不能有条件地要求该字段。如果对所有字段(甚至是空白字段)都运行了验证,则可以编写自定义验证器来抛出异常(如果它应该被要求而不是)。 JSF 有一些东西只是一种痛苦。除非/直到它们被修复,我们只需要处理它们。

在原始帖子中讨论问题的细节:这里的区别在于您在生命周期中所处的位置。 submit 方法看起来像是一个按钮的动作监听器,将其置于生命周期的末尾;动作和动作侦听器在渲染响应之前但在验证之后的“调用应用程序”阶段触发。如果您打算使用 JSF 进行编程,您应该学习并理解生命周期。值得花时间。

【讨论】:

  • 麦克道尔的回答更中肯。业务逻辑应该在 Invoke Application 阶段执行。您不应该需要提交或本地值,不应该执行一些多余的手动转换和验证。
  • 组件只是按照它们在组件树中出现的顺序进行处理(转换/验证)。没有模糊的魔法。
  • 关于您对条件验证的评论:实际上可以编写一个自定义验证器,并为它提供一个“其他”字段列表(=除了验证器工作的字段之外)应该考虑到 - 例如组中的字段应全部填写,或全部留空,例如护照号码+护照国家+有效期。 (谷歌“jsf 组验证器”)。由于处理顺序中有些字段可能在该字段之前和之后,因此可以使用isLocalValueSet()getValue()getSubmittedValue()来获取相关值以用于逻辑。
【解决方案2】:

引用EditableValueHolder.getSubmittedValue上的文档:

返回提交的Value值 这个组件。这种方法应该 仅由 encodeBegin() 使用 和/或 encodeEnd() 方法 组件,或其对应的 渲染器。

通常,您甚至不会调用 getValue。相反,组件的 value 属性应该绑定到您的模型(也许是一个 bean)。您的业​​务逻辑将与模型交互,而不是与组件交互。

如果提交的值没有被设置为值,那么我猜想某些验证失败了。唯一的问题是你的事件被触发了。这里的问题有两种猜测:

  • 您对组件对象的引用已过时。
  • 您在 UICommand 上设置了 immediate 属性,这意味着在组件处于不适当状态的阶段触发事件。

无法确定所提供的信息。

【讨论】:

  • 感谢您的洞察力,@McDowell。你为我提供了很多弹药来调查我的代码。荣誉。
  • 经过一番调查后,我意识到问题出在我的 JSP 标记中。我没有将控件的值绑定到 bean 属性,我只是设置组件绑定和数据源。在我绑定值后,一切都按预期工作,我消除了所有 getSubmittedValue()。
  • 是的,我们将如何在自定义验证器中访问此模型?不用了。
【解决方案3】:

我在基于 JSF 的 xpage 上工作,所以.. 可能是一样的...

无论如何,getSubmittedValue();始终返回您在 firebug/chrome 开发人员网络选项卡中看到的内容。那是发送数据包中的值。我在标题选项卡中显示(chrome),在表单数据部分中,名为 $$xspsubmitvalue。

另一方面,getValue() 是特定于组件的。

【讨论】:

    【解决方案4】:

    TL;DR 答案:

    UIViewRoot viewRoot = context.getViewRoot();
    UIInput input = (UIInput)viewRoot.findComponent(":form:inputID");
    
    String inputValueString;
    
    if (input.isLocalValueSet()) {
      inputValueString = (String)input.getValue(); //validated and converted already
    } else {
      inputValueString = (String)input.getSubmittedValue(); //raw input
    }
    

    或者至少这就是其他答案所说的......

    只需使用.getSubmittedValue() 并处理必须转换原始输入的后果(如有必要,如果该原始输入需要转换)。 .getValue() 在这方面被破坏了,即使是上面的代码。如果您使用它会延迟提交的值,这是不可接受的。

    【讨论】:

      猜你喜欢
      • 2011-11-15
      • 2013-05-29
      • 1970-01-01
      • 2018-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-11
      • 1970-01-01
      相关资源
      最近更新 更多