使用Ajax.update或getRenderIds()的UnsupportedOperationException。添加

时间:2013-05-16 14:01:32

标签: jsf-2 myfaces partial-page-refresh omnifaces

我正在尝试使用java代码刷新jsf组件。首先,我尝试使用它:

FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().add("MyCompId");

但它会产生“UnsupportedOperationException”。然后,我尝试安装omnifaces并使用Ajax.update(“MyComp”)。结果是一样的:

org.apache.myfaces.view.facelets.el.ContextAwareELException: javax.el.ELException: java.lang.UnsupportedOperationException
    at org.apache.myfaces.view.facelets.el.ContextAwareTagMethodExpression.invoke(ContextAwareTagMethodExpression.java:108)
    at org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:68)
    at javax.faces.component.UICommand.broadcast(UICommand.java:120)
    at javax.faces.component.UIViewRoot._broadcastAll(UIViewRoot.java:1041)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:289)
    at javax.faces.component.UIViewRoot._process(UIViewRoot.java:1415)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:765)
    at org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:38)
    at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:170)
    at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:117)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:197)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:357)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl._doFilterImpl(TrinidadFilterImpl.java:303)
    at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl.doFilter(TrinidadFilterImpl.java:208)
    at org.apache.myfaces.trinidad.webapp.TrinidadFilter.doFilter(TrinidadFilter.java:92)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)
Caused by: javax.el.ELException: java.lang.UnsupportedOperationException
    at org.apache.el.parser.AstValue.invoke(AstValue.java:291)
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274)
    at org.apache.myfaces.view.facelets.el.ContextAwareTagMethodExpression.invoke(ContextAwareTagMethodExpression.java:96)
    ... 34 more
Caused by: java.lang.UnsupportedOperationException
    at java.util.AbstractCollection.add(AbstractCollection.java:221)
    at org.omnifaces.util.Ajax.update(Ajax.java:75)

我尝试重现在此处找到的相同示例:http://showcase.omnifaces.org/utils/Ajax。 我的XHTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<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:c="http://java.sun.com/jsp/jstl/core">
<f:view  contentType="text/html">
    <h:body id="body">
        <h:form id="form">
            <div id="contentStyle">    
                <h:panelGroup styleClass="blocLsMsgErr" id="messages">
                    <h:panelGroup styleClass="lsMsgErr">
                        <h:dataTable var="facesMessage"
                            value="#{messagesComponent.listeCustomFacesMessage1}">
                            <h:column>
                                <h:graphicImage alt="icon"
                                    value="/images/messages/#{facesMessage.severity}_icon.png" />
                            </h:column>
                            <h:column>
                                <h:outputLink rendered="#{not empty facesMessage.id}"
                                    styleClass="titre #{facesMessage.severity}"
                                    onclick="document.getElementById('#{facesMessage.id}').focus();return false;">
                                    <h:outputText value="#{facesMessage.summary} " />
                                </h:outputLink>
                                <h:outputText rendered="#{empty facesMessage.id}"
                                    styleClass="titre #{facesMessage.severity}"
                                    value="#{facesMessage.summary} " />
                            </h:column>
                            <h:column>
                                <h:outputText styleClass="#{facesMessage.severity}"
                                    value=" -1- " />
                            </h:column>
                            <h:column>
                                <h:outputText styleClass="#{facesMessage.severity}"
                                    value="#{facesMessage.detail}" />
                            </h:column>
                        </h:dataTable>

                        <h:panelGrid columns="1">
                            <ui:repeat value="#{messagesComponent.listeCustomFacesMessage2}"
                                var="facesMessage">
                                <h:graphicImage alt="icon"
                                    value="/images/messages/#{facesMessage.severity}_icon.png" />
                                <h:outputLink rendered="#{not empty facesMessage.id}"
                                    styleClass="titre #{facesMessage.severity}"
                                    onclick="document.getElementById('#{facesMessage.id}').focus();return false;">
                                    <h:outputText value="#{facesMessage.summary} " />
                                </h:outputLink>
                                <h:outputText rendered="#{empty facesMessage.id}"
                                    styleClass="titre #{facesMessage.severity}"
                                    value="#{facesMessage.summary} " />
                                <h:outputText styleClass="#{facesMessage.severity}"
                                    value=" -2- " />
                                <h:outputText styleClass="#{facesMessage.severity}"
                                    value="#{facesMessage.detail}" />
                                <br />
                            </ui:repeat>
                        </h:panelGrid>

                        <h:panelGrid columns="4">
                            <c:forEach items="#{messagesComponent.listeCustomFacesMessage3}"
                                var="facesMessage">
                                <h:graphicImage alt="icon"
                                    value="/images/messages/#{facesMessage.severity}_icon.png" />
                                <h:outputLink rendered="#{not empty facesMessage.id}"
                                    styleClass="titre #{facesMessage.severity}"
                                    onclick="document.getElementById('#{facesMessage.id}').focus();return false;">
                                    <h:outputText value="#{facesMessage.summary} " />
                                </h:outputLink>
                                <h:outputText rendered="#{empty facesMessage.id}"
                                    styleClass="titre #{facesMessage.severity}"
                                    value="#{facesMessage.summary} " />
                                <h:outputText styleClass="#{facesMessage.severity}"
                                    value=" -3- " />
                                <h:panelGroup>
                                    <h:outputText styleClass="#{facesMessage.severity}"
                                        value="#{facesMessage.detail}" />
                                    <br />
                                </h:panelGroup>
                            </c:forEach>
                        </h:panelGrid>

                    </h:panelGroup>
                </h:panelGroup>

                <ui:insert name="content" />

                <h:commandButton styleClass="button"
                    value="#{messages.boutonSuivant}" id="buttonNext"
                    action="#{testBean.nextPage}">
                    <f:ajax />
                </h:commandButton>
            </div>
            <h:commandButton value="submit" action="#{testBean.update}">
                <f:ajax />
            </h:commandButton>
        </h:form>
    </h:body>
</f:view>
</html>

我的豆子:

import javax.inject.Named;

import org.omnifaces.util.Ajax;
import org.springframework.context.annotation.Scope;

@Named
@Scope("session")
public class TestBean {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public void update() {
        System.out.println("Ajax update");
        Ajax.update("messages");
        System.out.println("Ajax update OK");
    }

    public String nextPage() {

        if (!this.validationChampsPagePersonne()) {
            return null;

        }

        return "next";
    }

    private boolean validationChampsPagePersonne() {
    //doing a FacesContext.getCurrentInstance().addMessage(null, facesMessage);
    }

}

其他信息: 我正在使用myfaces api和implementation(版本2.1.11),trinidad 2.1.0,tomahawk2 1.1.14,primefaces 3.5

有什么想法吗?

由于

1 个答案:

答案 0 :(得分:1)

MyFaces不是原因,它一直在MyFaces为我们和其他任何人工作。然而,我们从未真正使用过特立尼达,所以我查看了特立尼达的源代码。它appears在没有渲染ID时返回Collections#emptySet()。但是这是immutable!这完全解释了您所面临的例外情况。

这是特立尼达的一个相当惊人的错误。 javadoc清楚地表明返回的集合必须是可变的。

  

使用请求参数名称Collection从当前请求中返回PARTIAL_RENDER_PARAM_NAME个客户端标识符。如果没有此类请求参数,则返回空Collection。这些客户端标识符用于标识将在请求处理生命周期的呈现阶段期间处理的组件。 返回的Collection是可变的。

如果你喜欢特立尼达,请将它作为一个错误报告给特立尼达人。否则只是摆脱它。如果您已经使用PrimeFaces(和Tomahawk),我认为没有任何理由使用它。