Omnifaces - ListIndexConverter,操作原理

Omnifaces - ListIndexConverter, principle of operation

我试着理解 omnifaces.converter.ListIndexConverter

@FacesConverter("omnifaces.ListIndexConverter")
public class ListIndexConverter implements Converter {

private static final String ERROR_LIST_INDEX_BOUNDS =
        "Index {0} for value {1} in component {2} is out of bounds.";

private static final String ERROR_VALUE_NOT_IN_LIST =
        "Object {0} in component {1} does not appear to be present in the given list.";

private List<?> list;

@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
    int index = Integer.valueOf(value);
    if (index < 0 || index >= list.size()) {
        throw new ConverterException(
            createError(ERROR_LIST_INDEX_BOUNDS, index, value, component.getClientId(context))
        );
    }

    return list.get(index);
}

@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
    for (int i = 0; i < list.size(); i++) {
        if (list.get(i).equals(value)) {
            return i + "";
        }
    }

    throw new ConverterException(
        createError(ERROR_VALUE_NOT_IN_LIST, value == null ? "null" : value.toString(), component.getClientId(context))
    );
}

public void setList(List<?> list) {
    this.list = list;
}

}

我调试了它,但无法弄清楚所有问题!

这是我的问题:

1) list 成员变量何时由谁填充?

2) 在文档中

http://omnifaces.org/docs/javadoc/2.0/org/omnifaces/converter/SelectItemsIndexConverter.html

提到了以下几点:

This converter has the following disadvantage over SelectItemsConverter:

The "Validation Error: value is not valid" will never occur anymore for the case that the available select items has incompatibly changed during the postback due to a developer's mistake. The developer should make absolutely sure that exactly the same list is preserved on postback (e.g. by making it a property of a view scoped or broader scoped bean).

(SelectItemsConverter可以换成ListConverter)

有人可以更详细地解释一下吗? 据我了解,它需要一个 @RequestScoped Bean 和一个可编辑的列表,就像用于 DataTable 的那样,才能引发这种情况? 出于教育原因,我想这样做并将其展示给其他开发人员。

希望我的问题很清楚!非常感谢任何解释!

When and by whom is the list member variable filled?

通过 <o:converter list> 属性,与展示柜的 Usage 部分完全相同。

<p:pickList value="#{bean.dualListModel}" var="entity" itemValue="#{entity}" itemLabel="#{entity.someProperty}">
    <o:converter converterId="omnifaces.ListIndexConverter" list="#{bean.dualListModel.source}" />
    <!-- ===================================================^^^^ -->
</p:pickList>

<o:converter> 是一个特殊的标记处理程序,它允许在引用的 Converter 实例上设置任意属性,就好像它是 bean 属性一样。


The "Validation Error: value is not valid" will never occur anymore [...]

有人可以更详细地解释一下吗?

所选项目 omnifaces.XxxIndexConverter 不再由它们自己的标识符标识,而是由它们在列表中的位置标识。如果列表在回发之间发生变化,如果 selected 项是列表的 really 部分并且最终用户 really[=,JSF 可以通过这种方式不再验证36=] 打算 select 正是那个项目。想象一下,该项目在列表中的位置由于被删除或在 selected 项目之前添加了更新的项目而发生了变化,那么您最终会得到错误的项目。有关背景说明,另请参阅 Validation Error: Value is not valid 上的答案。

如果这是一个安全问题,那么您最好选择 omnifaces.XxxConverter(没有 Index)。