繁体   English   中英

将filterBy添加到p:dataTable会在javax.faces.component.StateHolderSaver处引发java.lang.NullPointerException。 <init> 回发时

[英]Adding filterBy to p:dataTable causes java.lang.NullPointerException at javax.faces.component.StateHolderSaver.<init> on postback

我正在尝试开发具有延迟加载的数据表。 通过使用UserService(即简单的DAO),可以从持久性上下文正确加载未过滤和已过滤的记录。 我100%肯定该问题与所使用的DAO无关,因为它已经成功测试并部署在其他软件包中。

当我尝试插入过滤器时出现错误:已过滤项目的集合已正确加载到页面上,但看起来在过程结束时出现了问题,并引发了NPE。 此后,该表不再响应任何命令。

谢谢你的帮助!

以下是配置,视图和所使用的控制器。

组态

  • Wildfly 8.2.0
  • JDK 1.8.0_25
  • PrimeFaces 5.1

查看(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:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:p="http://primefaces.org/ui">

    <ui:composition template="/template/template.xhtml">

        <ui:define name="body">
            <h:form id="UserListForm">
                <p:panel header="#{bundle.ListUserTitle}">
                    <p:dataTable id="UserTable" value="#{userController.users}" var="user" lazy="true" rows="25"
                                 paginator="true" rowKey="#{user.id}" selectionMode="single" selection="#{userController.selected}"
                                 paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}" >

                        <p:column headerText="#{bundle.User_id}" filterBy="#{user.id}">
                           <h:outputText value="#{user.id}"/>
                        </p:column>
                        <p:column headerText="#{bundle.User_nickname}" filterBy="#{user.nickname}">
                           <h:outputText value="#{user.nickname}"/>
                        </p:column>

                    </p:dataTable>
                </p:panel>
            </h:form>

        </ui:define>
    </ui:composition>

</html>

控制者

import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;

@Named("userController")
@SessionScoped
@Transactional(Transactional.TxType.REQUIRED)
public class UserController implements Serializable {

    @Inject
    private UserService userService;

    private LazyUserDataModel users;
    private User selected;

    @PostConstruct
    public void init() {
        users = new LazyUserDataModel(userService);
    }

    public User getSelected() {
        return selected;
    }

    public void setSelected(User selected) {
        this.selected = selected;
    }

    public LazyUserDataModel getUsers() {
        return users;
    }

    public void setUsers(LazyUserDataModel users) {
        this.users = users;
    }

}

懒数据模型

import java.util.List;
import java.util.Map;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;

public class LazyUserDataModel extends LazyDataModel<User> {

    private List<User> data;
    private final UserService userService;

    public LazyUserDataModel(UserService userService) {
        this.userService = userService;
    }

    @Override
    public User getRowData(String rowKey) {
        Long id = Long.valueOf(rowKey);
        for (User u : data) {
            if (u.getId().equals(id))
                return u;
        }
        return null;
    }

    @Override
    public Object getRowKey(User u) {
        return u.getId();
    }

    @Override
    public List<User> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,Object> filters) {
        UserFilterCorrector.correct(filters);
        UserFilter filter = new UserFilter(filters, first, pageSize);
        FilteredDataModel<User> userDataModel = userService.findFilteredList(filter);
        data = userDataModel.getData();
        this.setRowCount(userDataModel.getCount().intValue());
        return data;
    }
}

例外

11:07:46,348 SEVERE [javax.enterprise.resource.webcontainer.jsf.application] (default task-97) Error Rendering View[/user/List.xhtml]: java.lang.NullPointerException
 at javax.faces.component.StateHolderSaver.<init>(StateHolderSaver.java:96) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
 at javax.faces.component.UIComponentBase.saveAttachedState(UIComponentBase.java:1746) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
 at javax.faces.component.ComponentStateHelper.saveMap(ComponentStateHelper.java:378) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
 at javax.faces.component.ComponentStateHelper.saveState(ComponentStateHelper.java:256) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
 at javax.faces.component.UIComponentBase.saveState(UIComponentBase.java:1552) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
 at javax.faces.component.UIData.saveState(UIData.java:1780) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
 at org.primefaces.component.datatable.DataTable.saveState(DataTable.java:1520) [primefaces-5.1.jar:5.1]
 at com.sun.faces.application.view.FaceletPartialStateManagementStrategy$3.visit(FaceletPartialStateManagementStrategy.java:482) [jsf-impl-2.2.8-jbossorg-1.jar:]
 at com.sun.faces.component.visit.FullVisitContext.invokeVisitCallback(FullVisitContext.java:151) [jsf-impl-2.2.8-jbossorg-1.jar:]
 at org.primefaces.component.api.UIData.visitTree(UIData.java:692) [primefaces-5.1.jar:5.1]
 at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
 at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
 at javax.faces.component.UIForm.visitTree(UIForm.java:371) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
 at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
 at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
 at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
 at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
 at com.sun.faces.application.view.FaceletPartialStateManagementStrategy.saveView(FaceletPartialStateManagementStrategy.java:472) [jsf-impl-2.2.8-jbossorg-1.jar:]
 at com.sun.faces.application.StateManagerImpl.saveView(StateManagerImpl.java:89) [jsf-impl-2.2.8-jbossorg-1.jar:]
 at javax.faces.application.StateManager.getViewState(StateManager.java:593) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
 at com.sun.faces.context.PartialViewContextImpl.renderState(PartialViewContextImpl.java:483) [jsf-impl-2.2.8-jbossorg-1.jar:]
 at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:325) [jsf-impl-2.2.8-jbossorg-1.jar:]
 at org.primefaces.context.PrimePartialViewContext.processPartial(PrimePartialViewContext.java:60) [primefaces-5.1.jar:5.1]
 at javax.faces.component.UIViewRoot.encodeChildren(UIViewRoot.java:1004) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
 at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1856) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
 at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:430) [jsf-impl-2.2.8-jbossorg-1.jar:]
 at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:133) [jsf-impl-2.2.8-jbossorg-1.jar:]
 at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
 at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
 at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120) [jsf-impl-2.2.8-jbossorg-1.jar:]
 at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.2.8-jbossorg-1.jar:]
 at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219) [jsf-impl-2.2.8-jbossorg-1.jar:]
 at javax.faces.webapp.FacesServlet.service(FacesServlet.java:647) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
 at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
 at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:61) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
 at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
 at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
 at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
 at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
 at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:56) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
 at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
 at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
 at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:63) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
 at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
 at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
 at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
 at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
 at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
 at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
 at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
 at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:261) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
 at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:247) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
 at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:76) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
 at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:166) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
 at io.undertow.server.Connectors.executeRootHandler(Connectors.java:197) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
 at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:759) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_25]
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_25]
 at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_25]

我通过删除具有null的过滤器值并将其替换为空对象来解决了我的问题。 您可以将断点放在jsf-api / 2.2.8 / jsf-api-2.2.8-sources.jar!/javax/faces/component/UIComponentBase.java:1746中,并查看过滤器映射中哪个值导致了错误然后将其替换为空对象或将其删除。 我希望这有帮助。

这必须是jsf api实现中的错误。 如您在答案@bcavlin中所述,在源代码中没有足够的空检查来存储具有映射到空对象的任何键的Map。 我对此提交了JIRA问题,并在其中进行了详细说明,请参阅 JAVASERVERFACES-4088 (旧java.net问题)。 JAVASERVERFACES-4092

我做到了:

  1. 反编译jboss-jsf-api_2.2_spec-2.2.11.jar
  2. 使用类javax.faces.components.StateHolderSaver创建一个新的proyect,然后粘贴反编译的代码。
  3. 将jboss-jsf-api_2.2_spec-2.2.11.jar添加为库
  4. 变更码:

     public StateHolderSaver(FacesContext context, Object toSave){ this.className=toSave.getClass().getName(); 

    至:

     public StateHolderSaver(FacesContext context, Object toSave){ this.className=toSave!=null?toSave.getClass().getName():null; 
  5. 清洁和建造

  6. 替换jboss-jsf-api_2.2_spec-2.2.11.jar中的已编译StateHolderSaver
  7. 运行服务器,它运行正常

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM