2012-12-03 33 views
3

使用JSF 2.1,钻嘴鱼科2.1.3,3.1.1的Glassfish和PrimeFaces 3.3.1副本ID

我试图在JSF处理加工场级别的安全性,在preRenderView事件上,并在需要将动态组件添加到JSF组件树时遇到问题。在第一次渲染时,一切正常,并且字段级安全性被处理。然而,在任何形式的更新之后,即使通过打印到控制台,我的添加代码也只会在每次更新时运行一次,但Mojarra会抱怨重复的ID。

看起来就好像Mojarra没有清除组件树的回发,因此每个后续的呈现更新都会将附加版本的组件添加到树中。

感谢任何人都可以提供的帮助。这是一些简单的示例代码。在commandButton上单击错误被引发。

的index.xhtml:

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:h="http://java.sun.com/jsf/html" 
     xmlns:f="http://java.sun.com/jsf/core" 
     xmlns:p="http://primefaces.org/ui" 
     > 
    <f:event listener="#{lifeCycle.event}" type="preRenderView" /> 
    <h:body> 
     <h:form id="form" prependId="false"> 
      <h:panelGroup id="testPanel"> 
       <h:inputText id="viewSec" value="viewSec node"/><br/> 
      </h:panelGroup> 
      <p:commandButton update="testPanel"/> 
     </h:form> 
    </h:body> 
</html> 

LifeCycle.java:

package com.dynamic.test; 

import java.io.Serializable; 
import java.util.List; 
import javax.faces.bean.ManagedBean; 
import javax.faces.bean.RequestScoped; 
import javax.faces.component.UIComponent; 
import javax.faces.component.UIViewRoot; 
import javax.faces.component.html.HtmlOutputText; 
import javax.faces.component.visit.VisitContext; 
import javax.faces.context.FacesContext; 
import javax.faces.event.ComponentSystemEvent; 

@ManagedBean 
@RequestScoped 
public class LifeCycle implements Serializable { 
    public void event(ComponentSystemEvent event){ 
     FacesContext facesContext = FacesContext.getCurrentInstance(); 
     UIViewRoot root = facesContext.getViewRoot(); 
     NodeInspector visitCallback = new NodeInspector(); 

     root.visitTree(VisitContext.createVisitContext(FacesContext.getCurrentInstance()), visitCallback); 

     List<UIComponent> securityEnabledComponents = visitCallback.getSecurityEnabledComponents(); 
     for (UIComponent securityEnabledComponent : securityEnabledComponents) { 

      if(securityEnabledComponent.getClientId().equals("viewSec")){ 
       List<UIComponent> childList = securityEnabledComponent.getParent().getChildren(); 
       int targetPosition = securityEnabledComponent.getParent().getChildren().indexOf(securityEnabledComponent); 

       HtmlOutputText outputTextComponent = new HtmlOutputText(); 
       outputTextComponent.setId(securityEnabledComponent.getId()); 
       outputTextComponent.setValue(securityEnabledComponent.getAttributes().get("value")); 

       childList.set(targetPosition, outputTextComponent); 
      } 
     } 
    } 
} 

NodeInspector.java

package com.dynamic.test; 

import java.util.ArrayList; 
import java.util.List; 
import javax.faces.component.UIComponent; 
import javax.faces.component.visit.VisitCallback; 
import javax.faces.component.visit.VisitContext; 
import javax.faces.component.visit.VisitResult; 
import javax.faces.context.FacesContext; 

public class NodeInspector implements VisitCallback { 
    private List<UIComponent> securityEnabledComponents = new ArrayList<UIComponent>(); 
    FacesContext facesContext = FacesContext.getCurrentInstance(); 

    @Override 
    public VisitResult visit(final VisitContext context, final UIComponent target) { 
     if(target.getClientId().equals("viewSec")){ 
      securityEnabledComponents.add(target); 
     } 
     return VisitResult.ACCEPT; 
    } 

    public List<UIComponent> getSecurityEnabledComponents() { 
     return securityEnabledComponents; 
    } 
} 

错误:

SEVERE: JSF1007: Duplicate component ID viewSec found in view. 
    ... +id: j_idt2 
     type: <html xmlns="http://www.w3.org/1999/xhtml"> 

     +id: j_idt3 
     type: [email protected] 
     +id: form 
     type: [email protected] 
      +id: testPanel 
      type: [email protected] 
      +id: viewSec <=============== 
      type: [email protected] 
      +id: viewSec <=============== 
      type: [email protected] 
      +id: j_idt4 
      type: <br/> 

      +id: j_idt5 
      type: [email protected] 
     +id: j_idt6 
     type: 
    </html>... 

    SEVERE: Error Rendering View[/index.xhtml] 
    java.lang.IllegalStateException: Component ID viewSec has already been found in the view. 
     at com.sun.faces.util.Util.checkIdUniqueness(Util.java:821)... 
+4

今天早上我刚才知道是什么导致了我的问题 - 我正在运行的Mojarra版本有一些bug,与动态修改树相关,后来大部分版本已经解决了这个bug [这里报道](http://java.net/jira/browse/JAVASERVERFACES-1826))。在修复错误的过程中,他们似乎遇到了我所做的同样的问题。修改树会导致大量的孤立节点闲置。这些节点实际上并不在呈现的HTML中,但是检查id唯一性不会更低。 –

+2

你应该发表评论作为答案。知道这很有用。 – KidTempo

回答

-1

检查您使用的Mojarra版本是否与Primefaces 3.3.1兼容。
使用最新版本的Primefaces 3.6。