目前,我正在处理一项任务,该任务涉及将项目的PrimeFaces库从PrimeFaces 3.2更新到6.0。
从3.5版到4.0版,有一个不向后兼容的PrimeFaces‘MenuModel中API的变化。
我处理的代码使用了类org.primefaces.component.menuitem.MenuItem,该类扩展了javax.faces.component.UICommand。
从PrimeFaces 4.0开始,org.primefaces.component.menuitem.MenuItem是一个接口,有一个新的类org.primefaces.component.menuitem.UIMenuItem实现了该接口,并扩展了javax.faces.component.UICommand。新的UIMenuItem类或多或少具有与旧MenuItem类相同的接口,至少它支持我正在处理的代码中使用的所有方法。
因此,显然,我更改了MenuItem对象的insantiation代码,以使用新的UIMenuItem类。这样做,代码编译就没有错误,但是它在运行时失败了,除了这个例外:
Dec 01, 2016 11:58:02 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet Faces Servlet threw exception
java.lang.IllegalArgumentException: 0
at javax.faces.component.UIComponentBase.validateId(UIComponentBase.java:542)
at javax.faces.component.UIComponentBase.setId(UIComponentBase.java:363)在调试器中,我可以看到,实际上有一些UIMenuItem对象,其id为0。
UIMenuItem对象都是由如下所示的工厂方法创建的:
public static MenuItem createNavigationMenuItem() {
UIMenuItem item = new UIMenuItem();
item.setStyle("padding: 0;");
item.setUpdate(":tableForm,:navForm");
item.addActionListener(actionListener);
return item;
}事情是这样的。这些UIMenuItem对象的in由以下代码在org.primefaces.model.menu.BaseMenuModel中设置
public void generateUniqueIds() {
this.generateUniqueIds(getElements(), null);
}
private void generateUniqueIds(List<MenuElement> elements, String seed) {
if(elements == null || elements.isEmpty()) {
return;
}
int counter = 0;
for(MenuElement element : elements) {
String id = (seed == null) ? String.valueOf(counter++) : seed + ID_SEPARATOR + counter++;
element.setId(id);
if(element instanceof MenuGroup) {
generateUniqueIds(((MenuGroup) element).getElements(), id);
}
}
}我读了如下代码:当generateUniqueIds()被调用时,elements参数引用的MenuElements将不可避免地获得0、1、2等的I。
现在请看一下javax.faces.component.UIComponentBase中的这个方法
private static void validateId(String id) {
if (id == null) {
return;
}
int n = id.length();
if (n < 1) {
throw new IllegalArgumentException("Empty id attribute is not allowed");
}
for (int i = 0; i < n; i++) {
char c = id.charAt(i);
if (i == 0) {
if (!Character.isLetter(c) && (c != '_')) {
throw new IllegalArgumentException(id);
}
} else {
if (!Character.isLetter(c) &&
!Character.isDigit(c) &&
(c != '-') && (c != '_')) {
throw new IllegalArgumentException(id);
}
}
}
}可以清楚地看到,以数字开头的it总是会导致IllegalArgumentException,这正是我的代码失败的地方!
现在我想知道:为什么PrimeFaces库中的代码为MenuElement对象提供了明显无效的ids (根据它正在构建的JSF代码)?
遵循第一编程规则,我确信PrimeFaces代码是很好的,我的困惑是建立在我自己缺乏理解的基础上的。但是,对我来说,BaseMenuModel中的代码是没有意义的。有没有人能帮我弄清楚什么是我得不到的?
发布于 2016-12-02 10:57:36
不能将MenuModel与UIMenuItems:https://github.com/primefaces/primefaces/issues/199混合
https://stackoverflow.com/questions/40911252
复制相似问题