2013-12-13 19 views
1

我有一個複合部件「schematic_question.xhtml」:操作方法添加到動態創建的複合

<composite:interface> 
<composite:attribute name="attributesString" /> 
<composite:attribute name="renderedSchematic" /> 
<composite:attribute name="action" targets="deleteQuestionButton" required="true" /> 
<composite:attribute name="questionIdToDelete" /> 
<composite:attribute name="parentToUpdate" /> 
<composite:attribute name="questionId" /> 
</composite:interface> 

<composite:implementation> 
<p:panelGrid id="#{cc.clientId}" columns="1" 
    rendered="#{cc.attrs.renderedSchematic}" 
    styleClass=" fullWidthNoMargin" 
    style="padding:0px !important ; width:767px;"> 

    <p:panel style="background: #D3D3D3; margin-bottom: 20px;"> 

     <p:outputLabel 
      value="#{msg.globalLabelQuestion}-#{msg.globalLabelId}: " /> 
     <p:outputLabel value="#{cc.attrs.questionId}" 
      style="width: 30px; display:inline-block;" /> 

     <p:outputLabel style="padding-left:350px;" 
      value="#{msg.globalLabelAttributes}: " /> 
     <p:outputLabel value="#{cc.attrs.attributesString}" 
      style="width: 100px; display:inline-block;" /> 

     <p:outputLabel 
      value="#{msg.globalLabelDeleteelement}:" /> 
     <p:commandLink id="deleteQuestionButton" styleClass="noBorders" value="delete" 
      icon="icon-close" title="#{msg.globalLabelDelete}" > 
      <f:param name="questionIdToDelete" 
       value="#{cc.attrs.questionIdToDelete}" /> 
     </p:commandLink> 
    </p:panel> 
</p:panelGrid> 
</composite:implementation> 

現在我創建通過Java代碼,該複合部件:

private boolean createAndInsertSchematicInfosForQuestion(final QuestionDtoInt questionDto, 
     final UIComponent parentElementId) { 
    final Map<String, String> valueExpressions = new HashMap<String, String>(); 

    if (questionDto == null) { 
     return false; 
    } 

    final String questionId = String.valueOf(questionDto.getId()); 

    final QuestionDtoWrapper wrapper = new QuestionDtoWrapper(questionDto); 
    valueExpressions.put("action", "#{" + controllerClassName + ".deleteQuestion()}"); 
    valueExpressions.put("questionIdToDelete", questionId); 
    valueExpressions.put("attributesString", wrapper.getAttributes()); 
    valueExpressions.put("renderedSchematic", "#{" + controllerClassName + ".schematicView}"); 
    valueExpressions.put("parentToUpdate", ":previewQuestionnaireElementsForm"); 
    valueExpressions.put("questionId", questionId); 

    try { 
     utils.includeCompositeComponent(parentElementId, "components", "schematic_question.xhtml", 
       RandomStringUtils.randomAlphabetic(15), valueExpressions); 
    } catch (final IOException e) { 
     LOG.logError("Schematic question component could not be created", e); 
     return false; 
    } 
    return true; 
} 

然後將其插入在與窗體對話的滾動面板中:

<p:dialog widgetVar="previewQuestionnaireDlg" modal="true" 
    height="850" appendToBody="true" dynamic="true" width="880" 
    closeOnEscape="false" resizable="false"> 
    <p:ajax event="close" update="previewQuestionnaireElementsForm" 
     listener="#{previewQuestionnaireController.clearPreviewPanelChilds()}" /> 
    <h:form id="previewQuestionnaireElementsForm" prependId="false"> 
     <p:panelGrid id="previewQuestionnairePanelGrid" columns="1" 
      styleClass="noBorders"> 
      <h1>#{msg.editquestionnaireLabelPreviewquestionnaire}</h1> 
      <p:panelGrid id="schematicViewPanelGrid" columns="2"> 
       <h:outputText value="Schematische Ansicht " /> 
       <p:selectBooleanCheckbox 
        value="#{previewQuestionnaireController.schematicView}"> 
        <p:ajax process="schematicViewPanelGrid" 
         update="questionnairePreviewPanel" /> 
       </p:selectBooleanCheckbox> 
      </p:panelGrid> 
      <br /> 
      <br /> 
      <p:scrollPanel id="questionnairePreviewPanel" style="height:640px; width:840px;" styleClass="noBorders" mode="native"> 

      </p:scrollPanel> 

      <br /> 

      <p:commandButton value="#{msg.globalButtonClose}" 
       action="#{previewQuestionnaireController.clearPreviewPanelChilds()}" 
       update="previewQuestionnaireElementsForm" ajax="true" 
       onclick="previewQuestionnaireDlg.hide();"> 
      </p:commandButton> 
     </p:panelGrid> 
    </h:form> 
</p:dialog> 

這一切都顯示正確。 但只要點擊按鈕一個NullPointerException occurres和方法不叫:

#|2013-12-13T09:56:13.400+0100|SEVERE|glassfish3.1.2|javax.enterprise.system.container.web.com.sun.enterprise.web|_ThreadID=100;_ThreadName=Thread-14;|WebModule[/QuesT]FullAjaxExceptionHandler: An exception occurred during processing JSF ajax request. Error page '/views/errors/error.xhtml' will be shown. 
java.lang.NullPointerException 
at javax.faces.component.UIComponentBase$AttributesMap.put(UIComponentBase.java:2414) 
at javax.faces.component.UIComponentBase$AttributesMap.put(UIComponentBase.java:2283) 
at com.sun.faces.el.CompositeComponentAttributesELResolver$ExpressionEvalMap.put(CompositeComponentAttributesELResolver.java:367) 
at com.sun.faces.el.CompositeComponentAttributesELResolver$ExpressionEvalMap.put(CompositeComponentAttributesELResolver.java:287) 
at javax.el.MapELResolver.setValue(MapELResolver.java:267) 
at com.sun.faces.el.DemuxCompositeELResolver._setValue(DemuxCompositeELResolver.java:255) 
at com.sun.faces.el.DemuxCompositeELResolver.setValue(DemuxCompositeELResolver.java:281) 
at com.sun.el.parser.AstValue.setValue(AstValue.java:217) 
at com.sun.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:291) 
at org.jboss.weld.el.WeldValueExpression.setValue(WeldValueExpression.java:64) 
at com.sun.faces.facelets.el.ContextualCompositeValueExpression.setValue(ContextualCompositeValueExpression.java:170) 
at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:131) 
at javax.faces.component.UIInput.updateModel(UIInput.java:818) 
at javax.faces.component.UIInput.processUpdates(UIInput.java:735) 
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242) 
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242) 
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242) 
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242) 
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242) 
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242) 
at javax.faces.component.UIForm.processUpdates(UIForm.java:281) 
at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:510) 
at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183) 
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1590) 
at javax.faces.component.UIForm.visitTree(UIForm.java:335) 
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601) 
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601) 
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601) 
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601) 
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601) 
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601) 
at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:376) 
at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:252) 
at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:183) 
at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:183) 
at javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:1229) 
at com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:78) 
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) 
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) 
at org.apache.myfaces.extensions.cdi.jsf2.impl.listener.phase.CodiLifecycleWrapper.execute(CodiLifecycleWrapper.java:95) 
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) 
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217) 
at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279) 
at org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:175) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java) 
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655) 
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595) 
at org.apache.catalina.core.StandardHostValve.__invoke(StandardHostValve.java:161) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java) 
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231) 
at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317) 
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195) 
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860) 
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757) 
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056) 
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229) 
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137) 
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104) 
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90) 
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79) 
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54) 
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) 
at com.sun.grizzly.ContextTask.run(ContextTask.java:71) 
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532) 
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) 
at java.lang.Thread.run(Thread.java:724) 
|#] 

如果我改變複合到

<composite:attribute name="actionDelete" /> 

和方法字符串添加到操作

action="#{cc.attrs.actionDelete}" immediate="true" 

的方法調用,但我得到這個異常:

 #|2013-12-12T17:48:16.169+0100|SEVERE|glassfish3.1.2|javax.enterprise.system.container.web.com.sun.enterprise.web|_ThreadID=102;_ThreadName=Thread-14;|WebModule[/QuesT] FullAjaxExceptionHandler:  An exception occurred during processing JSF ajax request. Error page '/views/errors/error.xhtml' will be shown.  
javax.faces.FacesException: Unable to resolve composite component from using page using EL expression '#{cc.attrs.deleteAction}' 
at com.sun.faces.facelets.tag.TagAttributeImpl$AttributeLookupMethodExpression.invoke(TagAttributeImpl.java:444) 
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88) 
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102) 
at org.apache.myfaces.extensions.cdi.jsf.impl.security.SecurityViolationAwareActionListener.processAction(SecurityViolationAwareActionListener.java:56) 
at org.apache.myfaces.extensions.cdi.jsf.impl.config.view.ViewControllerActionListener.processAction(ViewControllerActionListener.java:68) 
at org.apache.myfaces.extensions.cdi.jsf.impl.listener.action.CodiActionListener.processAction(CodiActionListener.java:58) 
at javax.faces.component.UICommand.broadcast(UICommand.java:315) 
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794) 
at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:935) 
at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78) 
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) 
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) 
at org.apache.myfaces.extensions.cdi.jsf2.impl.listener.phase.CodiLifecycleWrapper.execute(CodiLifecycleWrapper.java:95) 
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) 
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217) 
at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279) 
at org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:175) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java) 
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655) 
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595) 
at org.apache.catalina.core.StandardHostValve.__invoke(StandardHostValve.java:161) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java) 
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231) 
at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317) 
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195) 
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860) 
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757) 
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056) 
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229) 
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137) 
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104) 
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90) 
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79) 
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54) 
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) 
at com.sun.grizzly.ContextTask.run(ContextTask.java:71) 
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532) 
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) 
at java.lang.Thread.run(Thread.java:724) 
|#] 

現在我的問題: 爲什麼會有這些異常,但更重要的是這通常是可能的(複合組件+動態添加+動作方法)?

回答

0

我從來沒有找到一個工作解決方案。 所以我找了另一個,發現條件EL-語言:

<html xmlns="http://www.w3.org/1999/xhtml" 
xmlns:f="http://java.sun.com/jsf/core" 
xmlns:h="http://java.sun.com/jsf/html" 
xmlns:ui="http://java.sun.com/jsf/facelets" 
xmlns:p="http://primefaces.org/ui" 
xmlns:composite="http://java.sun.com/jsf/composite" 
xmlns:c="http://java.sun.com/jsp/jstl/core" 
xmlns:qt="http://java.sun.com/jsf/composite/components"> 

<composite:interface> 
<composite:attribute name="questionnaireElement" type="java.util.List" 
    required="true" /> 
<composite:attribute name="deleteQuestionAction" 
    method-signature="void f()" /> 
<composite:attribute name="deleteInfoelementAction" 
    method-signature="void f()" /> 
<composite:attribute name="deleteHeadelementAction" 
    method-signature="void f()" /> 
<composite:attribute name="renderedSchematic" required="true" /> 
<composite:attribute name="preview" /> 
<composite:attribute name="parentForm" /> 
</composite:interface> 

<composite:implementation> 
<c:forEach var="element" items="#{cc.attrs.questionnaireElement}"> 
     <c:choose> 
      <c:when test="#{element.question}"> 
       <p:panelGrid id="F#{element.id}" columns="1"> 
        <qt:schematic_question attributesString="#{element.attributes}" 
         renderedSchematic="#{cc.attrs.renderedSchematic}" 
         questionId="#{element.id}" 
         deleteAction="#{cc.attrs.deleteQuestionAction}" 
         parentToUpdate="#{cc.attrs.parentForm}" /> 
        <qt:question 
         label="#{element.getLanguageDependentName(localeBean)}" /> 
        <c:if test="#{element.answer.isAnswerTypeFreetext()}"> 
         <qt:answer_freetext 
          labelFreetext="#{element.answer.getDescriptionForCurrentLanguage(localeBean.locale)}" /> 
        </c:if> 
        <c:if test="#{element.answer.isAnswerTypeBi()}"> 
         <qt:answer_bioptions 
          disabled="#{cc.attrs.preview}" 
          btnNoOpinion="#{msg.antwortpoolButtoitemNoOpinion}" 
          labelBIOpts="#{element.answer.getDescriptionForCurrentLanguage(localeBean.locale)}" /> 
        </c:if> 
        <c:if test="#{element.answer.isAnswerTypeYesNo()}"> 
         <qt:answer_yesno 
          disabled="#{cc.attrs.preview}" 
          labelYesNo="#{element.answer.getDescriptionForCurrentLanguage(localeBean.locale)}" /> 
        </c:if> 
        <c:if test="#element.answer.isAnswerTypeFormat()}"> 
         <qt:answer_format 
          labelFormat="#{element.answer.getDescriptionForCurrentLanguage(localeBean.locale)}" /> 
        </c:if> 
        <qt:separator /> 
       </p:panelGrid> 
      </c:when> 
      <c:when test="#{element.infoelement}"> 
       <p:panelGrid id="I#{element.id}" columns="1"> 
        <qt:schematic_infoelement 
         deleteAction="#{cc.attrs.deleteInfoelementAction}" 
         infoelementId="#{element.id}" 
         parentToUpdate="#{cc.attrs.parentForm}" 
         renderedSchematic="#{cc.attrs.renderedSchematic}" /> 
        <qt:infoelement 
         label="#{element.getLanguageDependentName(localeBean)}" /> 
        <qt:separator /> 
       </p:panelGrid> 
      </c:when> 
      <c:when test="#{element.headelement}"> 
       <p:panelGrid id="K#{element.id}" columns="1"> 
        <qt:schematic_headelement 
         deleteAction="#{cc.attrs.deleteHeadelementAction}" 
         headelementId="#{element.id}" 
         parentToUpdate="#{cc.attrs.parentForm}" 
         renderedSchematic="#{cc.attrs.renderedSchematic}" /> 
        <qt:headelement 
         label="#{element.getLanguageDependentName(localeBean)}" /> 
        <qt:separator /> 
       </p:panelGrid> 
      </c:when> 
     </c:choose> 
    </c:forEach> 
</composite:implementation> 
</html> 

它做它的工作速度更快,更清潔。