【问题标题】:Contains on a list of Enums returns wrong result包含在枚举列表中返回错误结果
【发布时间】:2018-04-07 01:28:17
【问题描述】:

我正在尝试使用

有条件地渲染一个 primefaces 字段集
<p:fieldset legend="content" rendered="#{controller.object.list.contains('THREAD_PROTRUSION')}" >

其中 'THREAD_PROTRUSION' 是一个枚举。当我觉得应该渲染时,字段集没有渲染,所以我将这些输出添加到我的页面:

#{controller.object.list}<br/>
#{controller.object.list.contains('THREAD_PROTRUSION')}<br/>

然后显示如下

[THREAD_PROTRUSION, ENGAGE_NUT]
false

当 'THREAD_PROTRUSION' 在列表中时,为什么值 false

还有一点。该列表是从另一个屏幕上的复选框设置的,并通过加载 JSON 输入文件来填充。如果我返回带有复选框的视图并循环它们(取消选中,然后重新选中)然后返回带有我的字段集的视图,我看到了

[THREAD_PROTRUSION, ENGAGE_NUT]
true

当然现在渲染字段集

== MCV 示例

view.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:o="http://omnifaces.org/ui" xmlns:p="http://primefaces.org/ui" xmlns:bjap="http://bjap.gdeb.com/facelets">

<h:body>
                    <li><b>Enum List </b> #{bean.myList}</li>
                    <li><b>bean.myList[0] </b>#{bean.myList[0]}</li>
                    <li><b>bean.myList[1] </b>#{bean.myList[1]}</li>
                    <li><b>bean.myList.contains('RED') </b>#{bean.myList.contains('RED')}</li>
                    <li><b>bean.myList[0] eq 'RED' </b>#{bean.myList[0] eq 'RED'}</li>
                    <li><b>bean.myList[1] eq 'RED' </b>#{bean.myList[1] eq 'RED'}</li>
</h:body>
</html>

Bean.java

@Named
public class Bean implements Serializable {
    private static final long serialVersionUID = 1L;

    public enum Color {
        WHITE, BLACK, RED, YELLOW, BLUE
    }

    private List<Color> myList;

    public Bean() {
        myList = new ArrayList<>();
        myList.add(Color.WHITE);
        myList.add(Color.RED);
    }

    public List<Color> getMyList() {
        return myList;
    }

    public void setMyList(List<Color> myList) {
        this.myList = myList;
    }

}

输出

Enum List  [WHITE, RED]
bean.myList[0] WHITE
bean.myList[1] RED
bean.myList.contains('RED') false <-Expected to be true???
bean.myList[0] eq 'RED' false
bean.myList[1] eq 'RED' true

【问题讨论】:

  • 我改进了你的标题和标记。你能发一个minimal reproducible example吗?并发布版本信息(jsf impl,EL),因为我无法重现
  • 好的,谢谢。我会写一个完整的例子
  • 但是也让它最小化,并且可以验证
  • 抱歉,我在自己创建的示例中有错字,因此它“有效”。我现在可以重现,但同时我在 stackoverflow 中发现了一个“重复”的 Q/A。它有一个非常相似的标题,我想知道为什么它现在在右侧的“相关”Q/A 部分中不可见...stackoverflow.com/questions/35558683/…

标签: jsf el


【解决方案1】:

基于这个答案EL syntax to check if a set contains a specific Enum value,我现在明白为什么这是错误的,而我认为它是正确的。

#{controller.object.list.contains('THREAD_PROTRUSION')}

正如我在上面的问题中提到的,该列表最初是通过加载 JSON(fasterxml Jackson)来填充的。该列表支持一组 Primefaces 复选框。

我发现 Jackson 将复选框值加载为枚举(正如预期的那样),但是当我手动选择复选框时,列表中填充了字符串。我通过遍历我的列表并使用 instanceof 对照字符串和我的枚举检查每个值来发现这一点。

当列表包含字符串时,EL list.contains 工作,所以我的工作是更改我的列表

from 
List<MyEnum> list;
to 
List<String> list;

有了这个更改,Jackson 似乎仍然可以很好地序列化和反序列化我的复选框值,我可以使用 EL 检查列表是否包含枚举。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多