【问题标题】:How to access POST parameters when validation failed验证失败时如何访问 POST 参数
【发布时间】:2013-10-31 12:11:18
【问题描述】:

我需要根据某些输入字段显示响应页面。例如。 tabid input隐藏在下面:

#{controllerBean.tabId}
...
<h:form id="edit">
  <h:inputHidden value="#{controllerBean.tabId}" id="tabid" />
  <h:inputText value="#{controllerBean.name}" id="name" />
</h:form>

但是当同一表单中的其他一些输入出现验证错误时(例如“名称”inputText)。由于 JSF 在验证阶段返回,因此不会分配“controllerBean.tabId”值。

我仍然需要 tabId 才能正确显示页面并记住 2 个想法:

#{param['edit:tabid']}

或使用绑定:

#{tabId.value}
<h:inputHidden value="#{controllerBean.tabId}" id="tabid" binding="tabId" />

我的问题是,这两个中哪一个更好或最佳实践?还是有更好的方法来做到这一点?


更新:

注意。在我的具体情况下,tabid 是由客户端 javascript 设置的。

  1. 服务器回复 html 中的一些项目。
  2. Javascript 将这些项目放入页面上的不同选项卡中。
  3. 其中一个选项卡使用表单中的当前 tabid 将数据 POST 到服务器。

所以我的服务器需要知道 tabid 才能显示选择了正确选项卡的响应页面。

【问题讨论】:

  • 但是你在 managedBean 哪里需要它,但是如果发生验证错误,你的托管 bean 将不会被调用。
  • 不是我的 bean 需要它,而是我的页面。具体来说,我的页面需要 tabid 才能知道要显示哪个标签
  • 你有机会和@ViewScoped一起去吗?这将允许您在 bean 中保留当前选项卡 ID。
  • tabid是客户端javascript指定的,所以原页面没有。我认为视图范围也无济于事(不使用 ajax):( 用我的具体情况更新了问题。
  • 在 bean 中是否需要 tabId 用于其他用途?或者您是否只有一个属性+getter+setter,它在例如期间使用的 bean 中是 nowhere else行动?

标签: jsf jsf-2 jsf-2.2


【解决方案1】:

您可以将lifecycle event listener 添加到组件并从中选择值。我要推荐preValidate监听器:

 <h:form id="edit">
     <h:inputHidden value="#{controllerBean.tabId}" id="tabid">
         <f:event type="preValidate" listener="#{controller.grabTabId}"/>
     </h:inputHidden>
     <h:inputText value="#{controllerBean.name}" id="name" />
 </h:form>

这会将侦听器注册为在请求的验证阶段之前触发。您现在将在您的支持 bean 中定义一个侦听器,如下所示:

   public void grabTabId(ComponentSystemEvent cse){
     //obtain a reference to the component
     HtmlInputHidden hiddenElement = (HtmlInputHidden)cse.getComponent(); 
     //get the value from the component.
     String hiddenValue = hiddenElement.getValue();
   }

【讨论】:

    【解决方案2】:
    <h:form id="edit">
     <h:inputHidden value="#{controllerBean.tabId}" id="tabid" />
     <h:inputText value="#{controllerBean.name}" id="name" >
      <p:ajax process="tabid" immediate="true" event="keyup" />
     </h:inputText>
    </h:form>
    

    上面的代码将做的是当用户输入一些值时,该值将被处理并被设置为managedBean。我想这就是你想要的。

    【讨论】:

    • 感谢您的快速回答。我的controllerBean是requestScoped,我觉得ajax方式不行?
    • @Kai 然后至少使用@ViewScoped。而且我不建议每个 keyup 使用 ajax,文本中每个新字符可能会产生很多请求。
    • tabid由客户端javascript指定,原页面没有。所以我认为视图范围也无济于事(不使用ajax):(用我的具体情况更新了问题
    【解决方案3】:

    另一种不完美的方法是将验证逻辑移到您的操作方法中。如果验证失败,您只需停止处理(并添加适用的 FacesMessage)。您只需要注意所有模型值都已更新,如有必要,您可以清除它们。

    由于在验证失败时更新模型值违背了 JSF 生命周期,我认为任何解决方案都会有点像 hack。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-11
      • 2019-05-16
      • 2020-08-17
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      • 1970-01-01
      相关资源
      最近更新 更多