java.lang.NullPointerException 在 org.primefaces.util.ResourceUtils.getComponentResources

java.lang.NullPointerException at org.primefaces.util.ResourceUtils.getComponentResources

我正在使用 PF6.0 和 Wildfly 10,我的网络应用程序在某些时候需要在单个页面上构建一些相当大的 p:inplace 对象网格。听起来很简单。

问题:当我的网格太大时,任何 ajax 请求都以错误结束。

为了重现这个问题,我有工作示例:

页面test.xhtml:

<?xml version='1.0' encoding='UTF-8' ?>
<!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:h="http://java.sun.com/jsf/html"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:p="http://primefaces.org/ui">
    <h:head>
        <title>Test</title>
    </h:head>
    <h:body>
        <h:form>
            <!--it's a part of something bigger so this part is in outputPanel-->
            <p:outputPanel id="details">
                <h:outputText value="Size: #{backBean.size}" />
            <p:panelGrid>
                <!--btw. why it forces me to set all of this variables at p.repeat?--> 
                <p:repeat value="#{backBean.content}"
                          var="_row"
                          offset="0"
                          step="1"
                          size="#{backBean.content.size()}"
                          varStatus="_rowStatus" >
                    <p:row>
                    <p:repeat value="#{_row}" 
                              var="_cell" 
                              offset="0"
                              step="1"
                              size="#{_row.size()}"
                              varStatus="_rowStatus" >
                        <p:column>
                            <p:inplace editor="true">
                                <f:facet name="output">
                                        <h:outputText value="#{_cell.output}" />                                 
                                </f:facet>
                                <f:facet name="input">
                                    <!--in real example it will be more complex with checkboxes, selectonemenu etc-->
                                    <h:outputText value="First:" />
                                    <p:inputText value="#{_cell.something}" />
                                    <br />
                                    <h:outputText value="Second:" />
                                    <p:inputText value="#{_cell.another}" />
                                </f:facet>
                            </p:inplace>
                        </p:column>
                    </p:repeat>
                    </p:row>
                </p:repeat>
            </p:panelGrid>
            

        </p:outputPanel>
            <p:commandButton value="more" update="details" actionListener="#{backBean.weNeedMore}" />
        </h:form>
    </h:body>
</html>

支持 bean:

package com.test;

import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;


@Named(value = "backBean")
@SessionScoped
public class BackBean implements Serializable {

private List<List<CellContent>> content;
private int size;

/**
 * Creates a new instance of BackBean
 */
public BackBean() {
}

private void build() {
    content = new ArrayList<>();
    for(int i=0;i<size;i++) {
        List<CellContent> row = new ArrayList<>();
        for(int j=0;j<size;j++) {
            CellContent cell = new CellContent();
            row.add(cell);
        }
        content.add(row);
    }    
}

@PostConstruct
public void init() {
    size = 10;  

    //create first content
    build();
}

public void weNeedMore() {
    //increase until we get error after click.
    size = size + 10;
    build();
}

//plain getters & setters

public List<List<CellContent>> getContent() {
    return content;
}

public void setContent(List<List<CellContent>> content) {
    this.content = content;
}

public int getSize() {
    return size;
}

public void setSize(int size) {
    this.size = size;
}



}

还有一个 class 用来装我的东西:

package com.test;


public class CellContent {

private String something = "";
private String another = "";
private String output = "click_me";

public CellContent() {
}

//some dummy update based on inputs
private void update() {
    if(!something.equals(""))
        output = something;
    if(!another.equals(""))
        output = "another: " + another;
}

//those two setters update the object
public void setSomething(String something) {
    this.something = something;
    update();
}

public void setAnother(String another) {
    this.another = another;
    update();
}

//rest are plain get&seters
public String getSomething() {
    return something;
}

public String getAnother() {
    return another;
}

public String getOutput() {
    return output;
}

public void setOutput(String output) {
    this.output = output;
}


}

当我的对象网格 "small" 像 10x10 或 20x20 时它工作 - 我可以点击并更新任何单元格。

但是将大小增加到 30(通过点击更多按钮)会在我点击任何内容时导致此错误:

09:47:13,602 ERROR [io.undertow.request] (default task-89) UT005023: Exception handling request to /myapp/test.xhtml: javax.servlet.ServletException at javax.faces.webapp.FacesServlet.service(FacesServlet.java:671) at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:100) at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131) at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.security.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:51) at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) at io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:56) at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50) at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:284) at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:263) at io.undertow.servlet.handlers.ServletInitialHandler.access[=15=]0(ServletInitialHandler.java:81) at io.undertow.servlet.handlers.ServletInitialHandler.handleRequest(ServletInitialHandler.java:174) at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202) at io.undertow.server.HttpServerExchange.run(HttpServerExchange.java:793) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Caused by: java.lang.NullPointerException at org.primefaces.util.ResourceUtils.getComponentResources(ResourceUtils.java:66) at org.primefaces.context.PrimePartialResponseWriter.startMetadataIfNecessary(PrimePartialResponseWriter.java:280) at org.primefaces.context.PrimePartialResponseWriter.startError(PrimePartialResponseWriter.java:107) at com.sun.faces.context.AjaxExceptionHandlerImpl.handlePartialResponseError(AjaxExceptionHandlerImpl.java:203) at com.sun.faces.context.AjaxExceptionHandlerImpl.handle(AjaxExceptionHandlerImpl.java:127) at javax.faces.context.ExceptionHandlerWrapper.handle(ExceptionHandlerWrapper.java:100) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:119) at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:123) at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658) ... 34 more

知道发生了什么吗?有没有我可以调整的参数来避免这个错误?或任何其他解决方案(我当前的解决方法是使用带分页的数据网格)。

找到了 ;)

我切换回 PF 5.3 以检查它是否是 PrimeFaces 问题。 没有p:repeat@PF5.3 所以我换成ui:repeat.

这里也是一样,但错误消息最终说明了发生了什么:

10:37:58,508 SEVERE [javax.enterprise.resource.webcontainer.jsf.context] (default task-44) java.lang.IllegalStateException: UT000047: The number of parameters exceeded the maximum of 1000 at io.undertow.server.handlers.form.FormData.add(FormData.java:78) at io.undertow.server.handlers.form.FormData.add(FormData.java:68)

我需要做的就是在独立配置中更新 http-listener 的最大参数值:

 <subsystem xmlns="urn:jboss:domain:undertow:3.0">
            <buffer-cache name="default"/>
            <server name="default-server">
                <http-listener name="default" max-parameters="10000" socket-binding="http" redirect-socket="https"/>

(在 https://developer.jboss.org/thread/241526 找到)