Primefaces ajaxExceptionHandler 在 liferay 7 中不起作用

Primefaces ajaxExceptionHandler not working in liferay 7

Primefaces 6.1 ajaxExceptionHandler 在 liferay 7 portlet 中未按预期工作。 根据 Primefaces 用户指南,我尝试实现简单的异常处理。按下 commandButton 时,支持 bean 抛出 NullPointerException,它应该显示在对话框 window 中。问题是,弹出对话框时,并没有显示异常信息。似乎返回的 ajax 响应本身包含异常信息(如下所示),但对话框组件没有相应更新。

test.xhtml(片段)

<h:body>

    <h:form>
        <h3 style="margin-top:0">AJAX 1410</h3>
        <p:commandButton actionListener="#{policyAdminBean.throwNpe}"
                         ajax="true"
                         value="Throw NullPointerException!" />

        <p:ajaxExceptionHandler type="javax.faces.application.ViewExpiredException"
                                update=":exceptionDialog"
                                onexception="PF('exceptionDialogVar').show();" />

        <p:ajaxExceptionHandler type="java.lang.NullPointerException"
                                update=":exceptionDialog"
                                onexception="PF('exceptionDialogVar').show();" />
    </h:form>

    <p:dialog id="exceptionDialog" header="Exception '#{pfExceptionHandler.type}' occured!" widgetVar="exceptionDialogVar"
              height="500px">
        Message: #{pfExceptionHandler.message} <br/>
        StackTrace: <h:outputText value="#{pfExceptionHandler.formattedStackTrace}" escape="false" /> <br />

        <p:button onclick="document.location.href = document.location.href;"
                  value="Reload!"
                  rendered="#{pfExceptionHandler.type == 'javax.faces.application.ViewExpiredException'}" />
    </p:dialog>


</h:body>

TestBean.java

@Named
@ViewScoped
public class TestBean implements Serializable {
    private static final long serialVersionUID = -4856350663999482370L;

    public void throwNpe(){
        throw new NullPointerException("test exception");
    }
}

面孔-config.xml(片段)

<application>
        <message-bundle>Language</message-bundle>
        <locale-config>
            <default-locale>hu</default-locale>
        </locale-config>
        <el-resolver>
            org.primefaces.application.exceptionhandler.PrimeExceptionHandlerELResolver
        </el-resolver>
    </application>
    <lifecycle>
        <phase-listener>com.liferay.faces.util.lifecycle.DebugPhaseListener</phase-listener>
    </lifecycle>
    <factory>
        <exception-handler-factory>
            org.primefaces.application.exceptionhandler.PrimeExceptionHandlerFactory
        </exception-handler-factory>
    </factory>

ajax 响应(片段)

<partial-response id="_policyadmin_WAR_wfsadminportlets_">
    <update id="_policyadmin_WAR_wfsadminportlets_:exceptionDialog"><![CDATA[
        <div id="_policyadmin_WAR_wfsadminportlets_:exceptionDialog"
             class="ui-dialog ui-widget ui-widget-content ui-corner-all ui-shadow ui-hidden-container">
            <div class="ui-dialog-titlebar ui-widget-header ui-helper-clearfix ui-corner-top"><span
                    id="_policyadmin_WAR_wfsadminportlets_:exceptionDialog_title" class="ui-dialog-title">Exception 'java.lang.NullPointerException' occured!</span><a
                    href="#" class="ui-dialog-titlebar-icon ui-dialog-titlebar-close ui-corner-all"
                    aria-label="Close"><span class="ui-icon ui-icon-closethick"></span></a></div>
            <div class="ui-dialog-content ui-widget-content">
                Message: test exception <br/>
                StackTrace: java.lang.NullPointerException: test exception<br/> at

                [removed for brevity...]

                java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)<br/> at
                java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)<br/> at
                java.lang.Thread.run(Thread.java:745)<br/> <br/></div>
        </div>
        <script id="_policyadmin_WAR_wfsadminportlets_:exceptionDialog_s" type="text/javascript">$(function () {
            PrimeFaces.cw("Dialog", "exceptionDialogVar", {
                id: "_policyadmin_WAR_wfsadminportlets_:exceptionDialog",
                height: "500px"
            });
        });</script>
        ]]>
    </update>
    <eval><![CDATA[var
        hf=function(type,message,timestampp){PF('exceptionDialogVar').show();};hf.call(this,"java.lang.NullPointerException","test
        exception","2017-04-25 14:54:55");]]>
    </eval>
</partial-response>

问得好!

PrimeFaces AJAX 异常处理程序的这种使用模式在版本 6.0 之前的 PrimeFaces 中有效。因此,如果您回过头来说,PrimeFaces 5.3, you will see it working on Liferay 7. The commit that broke PrimeFaces was e22e40a,这是一个复杂的提交,通过更改 PrimeFaces 部分响应的构造方式在不知不觉中影响了 portlet。

A pull request has been sent to the PrimeFaces integrators 来解决这个问题。 https://github.com/primefaces/primefaces/pull/2333

合并此拉取请求后,您可以build PrimeFaces from the latest source,您会看到它已修复。

详情: 具体来说,提交 e22e40a 更改了 PrimePartialResponseWriter.startDocument() 方法,eliminating its call to encodeCallbackParams() which, in turn, was calling the startChangesIfNecessary() method in mojarra. Since these calls were eliminated, no "changes" element was introduced into the partial response. With no changes, no update occurs in the dialog's DOM. Here is a working stack showing the calls down into startChangesIfNecessary 在 e22e40a 提交之前。