2012-12-03 6 views
3

JSF 2.1, 인 Mojarra 2.1.3, 글래스 피시 3.1.1 및 PrimeFaces 3.3.1중복 ID

내가 JSF에서 처리 필드 수준 보안을 처리하기 위해 노력하고있어 사용, preRenderView 이벤트에서 동적 구성 요소를 JSF 구성 요소 트리에 추가해야 할 때 문제가 발생합니다. 첫 번째 렌더링에서는 모든 것이 잘되고 필드 레벨 보안이 처리됩니다. 그러나 어떤 종류의 업데이트 이후에도, Mojarra는 콘솔에 인쇄함으로써 코드 추가가 업데이트 당 한 번만 실행 되더라도 중복 ID에 대해 불평합니다.

Mojarra가 포스트 백을 위해 구성 요소 트리를 지우지 않아서 이후의 각 렌더링 된 업데이트가 구성 요소의 추가 버전을 트리에 추가하는 것처럼 보입니다.

누구나 제공해 주신 모든 도움에 감사드립니다. 몇 가지 간단한 샘플 코드가 있습니다. commandButton 클릭하면 오류가 throw됩니다.

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의 버전에는 버그가 많았습니다. 동적으로 트리를 수정하는 것과 관련하여, 그 이후로는 대부분 최신 버전에서 해결되었습니다. 여기에보고하십시오] (http://java.net/jira/browse/JAVASERVERFACES-1826)). 버그를 수정하는 과정에서, 그들은 내가했던 것과 똑같은 문제에 봉착 한 것처럼 보였다. 나무를 수정하면 수 많은 고아 노드가 주변에 앉아있게됩니다. 이 노드는 실제로 렌더링 된 HTML에 없지만 ID 고유성은 그다지 적습니다. –

+2

이 의견을 답으로 게시해야합니다. 알아두면 유용합니다. – KidTempo

답변

-1

사용중인 Mojarra의 버전이 Primefaces 3.3.1과 호환되는지 확인하십시오.
최신 버전의 Primefaces 3.6을 사용하십시오.

관련 문제