【问题标题】:JSF using EL to test global messages presenceJSF 使用 EL 测试全局消息的存在
【发布时间】:2012-07-31 09:06:29
【问题描述】:

我试图仅在 JSF 队列中有全局消息时才显示块。

我尝试使用rendered="#{not empty facesContext.getMessageList(null)}",但它总是被评估为假。

我发现的唯一方法是创建一个自定义 EL 函数并在 java 中对其进行测试。

例如。 : 我的 el 函数:

public static boolean isFacesGlobalMessages() {
  return ! FacesContext.getCurrentInstance().getMessageList(null).isEmpty();
}

JSF 页面:

<h:panelGroup class="block1" layout="block" rendered="#{el:isFacesGlobalMessages()}">
  <div class="block-warn-body">
    <rich:messages id="msg" globalOnly="true"/>
  </div>
</h:panelGroup>

我正在使用 Mojarra 2.1.5。

我错过了什么吗? 谢谢!

编辑:尝试了以下建议,但到目前为止没有运气:

  • #{not empty facesContext.getMessageList(null)} -> 总是错误的
  • #{! facesContext.getMessageList(null)} -> 错误
  • #{! empty facesContext.getMessageList(null)} -> 总是假的
  • #{fn:length(facesContext.getMessageList(null)) &gt; 0} -> 总是错误的
  • #{not empty facesContext.messageList(null)} -> 错误:找不到方法消息列表
  • #{not empty facesContext.messageList} -> 如果是验证错误,则返回 true(我只希望全局错误为 true)
  • #{! facesContext.getMessageList(null).isEmpty()} -> 抛出 IllegalAccessException:类 javax.el.BeanELResolver 无法访问带有修饰符“public”的类 java.util.Collections$UnmodifiableCollection 的成员

【问题讨论】:

  • 您是否尝试以与您的函数相同的方式编写它。 EL 知道!运算符。
  • 谢谢!刚试过(见上面的编辑),但没有奏效
  • @gonzalad ,不知道它是否对你有好处,但我更新了我的答案......

标签: jsf


【解决方案1】:

不需要自定义EL函数

试试这个

rendered="#{not empty facesContext.messageList}"

编辑

自己没试过,不过试试

rendered="#{not empty facesContext.messageList(null)}"

一个想法...

 rendered="#{not facesContext.validationFailed and not empty facesContext.messageList}"

【讨论】:

  • FacesContext#getMessageList() 返回所有条消息,以及非全局消息。
  • 试过 #{not empty facesContext.messageList(null)} 但它会产生异常(有关更多信息,请参阅上面的编辑)
  • 如果您想查明当您在消息列表中收到消息并且同时没有验证失败时的情况,请查看我编辑的答案......
  • 非常感谢丹尼尔!最后一个提议效果很好。我发现的唯一极端情况是,如果我从 java 代码添加本地 jsf 消息(例如 Messages.addError("form:nom", "Erreur spécifique"))。但是你的解决方案会很好,我会放弃我的自定义 el 函数。
【解决方案2】:

我知道这是一个旧线程,但在努力寻找难以捉摸的解决方案后,我找到了对此行为的解释,并且由于我无法在任何地方找到此解释(不知道为什么),我认为这可能会有所帮助。

我做了一个 el 函数略有不同:

public static boolean hasMessages(String clientId) {
    return !FacesContext.getCurrentInstance().getMessageList(clientId).isEmpty();
}

区别在于参数clientId。此函数的行为与使用#{not empty facesContext.getMessageList(clientId)} 完全相同。调试代码,我注意到当我用clientId = null调用函数时,函数内部clientId的值实际上是""(空字符串)。

之后我查阅了EL 3.0 Spec,发现:

第 1.23 节 - 类型转换

每个表达式都在预期类型的​​上下文中进行评估。表达式评估的结果可能与预期类型不完全匹配,因此应用以下部分中描述的规则。 [...]

第 1.23.2 节 - 将 A 强制转换为字符串

如果 A 为空:返回 "" [...]

所以,我认为没有办法使用clientId = nullnull 值作为参数传递来请求消息。唯一的方法是拥有一个不使用参数或测试参数是否设置为空字符串的函数。

【讨论】:

  • 不错的收获。这是 Oracle EL impl 中的一个已知错误,已在 a.o. WildFly 8.2 / GlassFish 4.1 和更新版本。 Tomcat 后来在 Apache EL 中重新引入了相同的错误,该错误从未得到“修复”,并且需要自定义 EL 解析器。相关:balusc.omnifaces.org/2015/10/the-empty-string-madness.html
  • @BalusC 我实际上是在使用 Glassfish 4.1 和 Oracle EL impl (v. 3.0.1-b03)。也许它不被认为是一个错误,因为它在规范中,但肯定有义务实现自定义函数/解析器只是为了做这样简单的事情。
  • 已在 3.0.1-b05 中修复。也许它在 4.1.1 中。
【解决方案3】:

试试这个:

rendered="#{not empty facesContext.getMessageList(null)}

代替:

rendered="#{not empty facesContext.messageList(null)}"

在丹尼尔的回答中。

或者这个:

rendered="#{not empty facesContext.getMessageList('inputForm')}

“inputForm”在哪里:

<h:form id="inputForm">
...
</h:form>

如果您只想将其发送到页面上的几种表单中的一种。

【讨论】:

    猜你喜欢
    • 2013-07-03
    • 2023-03-11
    • 2013-11-01
    • 1970-01-01
    • 2012-01-06
    • 2014-01-19
    • 1970-01-01
    • 2020-04-22
    相关资源
    最近更新 更多