【问题标题】:NullPointerException Error when trying to get a value from Another Bean in JSF尝试从 JSF 中的另一个 Bean 获取值时出现 NullPointerException 错误
【发布时间】:2011-12-11 23:33:54
【问题描述】:

我有两个支持豆:

  • Login:使用数据库表验证用户登录信息(用户名和密码)的 bean。
  • Buss_Services:另一个执行某些业务服务的 bean。

我需要从 Login bean 中获取用户 ID 并在 Buss_Services 中使用它。它存储在Login 的String 属性中,Buss_Services 需要此值来跟踪当前登录的用户并更新数据库。

这是 Login 支持 bean:

@ManagedBean(name="Login")
@SessionScoped
public class Login {
    private String loggedUserID;

    public Object logCB_action() {
        try {
            // ...
            rs = stmt.executeQuery(SQL);
            while (rs.next()) {
                if (rs.getString("USER_NAME").equals(uname)) {
                    if (rs.getString("USER_PW").equals(pword)) {

                     // Here, the user ID is set.
                    loggedUserID=rs.getString("USER_ID");// This line ...


                    System.out.println("Logged User (ID): "+ userID);

                        return ("displayApp");
                    }
                }
            }
        }

        // ...
    }        

    public String getLoggedID() {
        // Here, the user ID is returned.
        String id = loggedUserID;
        return (id);
    }

}

这是调用getLoggedID() 方法的Buss_Services 支持bean:

@ManagedBean(name="Buss_Services")
@SessionScoped
public class Buss_Services {



    @ManagedProperty("#{Login}")
    private Login login;

    public void newEst_action() {
        // The following line throws NullPointerException.
        System.out.println("Logged User (ID): " + login.getLoggedID());       
    }

    // Getters/setters.
}

这是我尝试访问业务服务页面时得到的堆栈跟踪:

javax.faces.el.EvaluationException:
//C:/Users/Sultan09/AppData/Roaming/JDeveloper/system11.1.2.0.38.60.17/o.j2ee/drs/TheOCES/OCES.ViewControllerWebApp.war/App_Business_SerivesPG.jsf @68,140 action="#{backingBeanScope.App_BServPG_Bean.newEst_action}": java.lang.NullPointerException

at org.apache.myfaces.trinidad.component.MethodExpressionMethodBinding.invoke(MethodExpressionMethodBinding.java:51)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
at org.apache.myfaces.trinidad.component.UIXCommand.broadcast(UIXCommand.java:190)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:787)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1252)
at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._invokeApplication(LifecycleImpl.java:965)
at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._executePhase(LifecycleImpl.java:346)
at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:204)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:312)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:300)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
at oracle.adf.model.servlet.ADFBindingFilter.doFilter(ADFBindingFilter.java:173)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
at oracle.adfinternal.view.faces.webapp.rich.RegistrationFilter.doFilter(RegistrationFilter.java:121)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:468)
at oracle.adfinternal.view.faces.activedata.AdsFilter.doFilter(AdsFilter.java:60)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:468)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl._doFilterImpl(TrinidadFilterImpl.java:293)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl.doFilter(TrinidadFilterImpl.java:199)
at org.apache.myfaces.trinidad.webapp.TrinidadFilter.doFilter(TrinidadFilter.java:92)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
at oracle.security.jps.ee.http.JpsAbsFilter$1.run(JpsAbsFilter.java:111)
at java.security.AccessController.doPrivileged(Native Method)
at oracle.security.jps.util.JpsSubject.doAsPrivileged(JpsSubject.java:313)
at oracle.security.jps.ee.util.JpsPlatformUtil.runJaasMode(JpsPlatformUtil.java:413)
at oracle.security.jps.ee.http.JpsAbsFilter.runJaasMode(JpsAbsFilter.java:94)
at oracle.security.jps.ee.http.JpsAbsFilter.doFilter(JpsAbsFilter.java:161)
at oracle.security.jps.ee.http.JpsFilter.doFilter(JpsFilter.java:71)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
at oracle.dms.servlet.DMSServletFilter.doFilter(DMSServletFilter.java:136)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3715)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3681)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2277)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2183)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1454)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:178

 Caused by: java.lang.NullPointerException
    at JavaView.backing.Buss_Services.newEst_action(Buss_Services.java:172)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.sun.el.parser.AstValue.invoke(Unknown Source)
    at com.sun.el.MethodExpressionImpl.invoke(Unknown Source)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    at org.apache.myfaces.trinidad.component.MethodExpressionMethodBinding.invoke(MethodExpressionMethodBinding.java:46)
    ... 44 more

这是怎么引起的,我该如何解决?


更新: 根据此处的 cmets 和个人搜索与此处所述的类似问题,问题终于解决了,感谢上帝。 解决方案是我必须:

  1. 将登录的<managed-property>添加到adfc-config.xml文件中。
  2. 更重要的是,在@PostConstruct 带注释的方法init() 中获取loggedUserID。谢谢大家。

【问题讨论】:

  • 不使用HtmlInputText,不如直接使用String
  • 我试过了,不幸的是同样的问题......

标签: jsf nullpointerexception


【解决方案1】:
System.out.println("Logged User (ID): " + login.get_final_logged_ID());       

该行上的NullPointerException 唯一可能的原因是loginnull。鉴于@ManagedProperty 看起来不错,这可能只有一个原因:setter 方法setLogin() 已损坏。确保它看起来完全像这样:

public void setLogin(Login login) {
    this.login = login;
}

因此不是

public void setLogin(Login login) {
    login = login;
}

或者别的什么。


更新根据 cmets:

至于 faces-config.xml ,事情是这样的,登录和业务服务 bean,对于它们各自的 jsf 页面,在<managed-bean-scope> 中被定义为“backingBean”。如您所见,在 java bean 中,我将它们定义为 sessionScoped。

最后,有你的问题的原因。 faces-config.xml 中的配置 覆盖 相关 bean 上的所有 JSF2 注释。您显然没有在faces-config.xml 中配置<managed-property>。你有两个选择:

  1. 删除faces-config.xml 中的整个<managed-bean> 配置。 @ManagedBean@ManagedProperty 等新 JSF 2.x 注释的全部意义在于摆脱冗长的 JSF 1.x 样式 XML 配置。

  2. <managed-property> 的值#{Login} 添加到Buss_Services<managed-bean>

    <managed-property>
        <property-name>login</property-name>
        <value>#{Login}</value>
    </managed-property>
    

与具体问题无关。你的设计和代码风格有几个严重的缺陷。

  • 您应该UIComponents 引用为属性。相反,您应该引用它的值。保持模型尽可能简单,除非你有真正正当的理由,否则永远不要使用UIComponent。例如

    private String username;
    private String password;
    private Long userID;
    
  • 您的登录验证方法效率低下。它似乎将整个用户表从 DB 拖到 Java 的内存中,您可以在其中测试每一行。您应该尽可能地编写和微调 SQL 查询,以便它准确地返回您正在寻找的信息。

    statement = connection.prepareStatement("SELECT id FROM Users WHERE username = ? AND password = MD5(?)");
    statement.setString(1, username);
    statement.setString(2, password);
    resultSet = statement.executeQuery();
    
    if (resultSet.next()) {
        userID = resultSet.getLong("id");
    }
    
  • 您的类似 PHP 的代码风格与 Java Naming Conventions 完全矛盾。它使所有其他 Java 开发人员更难阅读和维护代码,例如当您在 Internet 上发布代码时期望得到答案的开发人员,例如这里。包名应该全部小写。下划线仅在常量中有效,所有其他名称都应使用 CamelCase。实例名称(如托管 bean 名称)应以小写字母开头。等等。

【讨论】:

  • 我仔细检查了登录 bean 对象的 setter 和 getter 方法是否有任何问题,它们看起来很好,但我直到得到同样的错误!!! .非常感谢先生的其他重要提示..
  • 可以肯定,这是完整的堆栈跟踪? 真正的根本原因是最底层的部分。
  • JSF 应该调用 setLogin() 方法,因为您有一个 @ManagedProperty。您需要检查是否调用了该方法。在其上放置调试断点或添加System.out.println()/logger.debug() 行。
  • 感兴趣的变量login。似乎“调试”的概念对您来说是全新的。我建议您对此进行更多了解。调试基本上归结为逐行跟踪代码执行并检查哪些方法都被调用以及哪些变量都在堆栈中等等。它将产生关于代码执行期间发生的事情的非常有用的信息。
  • 好的,这就解释了。因此,@ManagedProperty 从未被调用过。造成这种情况的唯一合理原因可能是 @ManagedBean 不是来自 javax.faces.bean 包。但在你的情况下,问题似乎更深。您到底在使用什么 JSF impl/version?您使用的是什么 Weblogic 版本?您是否重新定义了 faces-config.xml 中的 bean?
【解决方案2】:

Ok NullPointerException 是一类非常普遍的错误,与 jsf 或您的数据库访问层等无关。据我从堆栈跟踪中可以看出,它是从您尚未提供任何代码的 newEst_action 函数内部抛出的。转到该函数中的特定行,即 172,看看你是否在做类似的事情

 myObject.doSomething()

如果不检查对象是否为空,如果 myObject 为空,它可能会抛出 NPE,所以请执行类似的操作

if (myObject!=null)
    myObject.doSomething()

【讨论】:

  • 这又是第 (172) 行:System.out.println("Logged User (ID): "+login.get_final_logged_ID());
  • .get_final_logged_ID() 应该返回 logged_user_ID 的值...为了进一步澄清,Logged_user_ID(HTML 输入文本)在接受有效的用户名/密码组合时设置一个值,在相同的代码中我的意思是块。再次检查登录 calss,希望它更清楚。
  • @user1092784 好的,我认为我们可以将其归结为 login 为 null 并且可能有很多原因...可以看到的明显原因之一是您没有 setLogin() 方法对于托管财产。尝试添加 public void setLogin(Login login){this.login=login;}
  • @ChinPing 我已经添加了 get 和 setLogin 方法,仍然是同样的错误!!
【解决方案3】:

请在打印 id 时检查您的 ManagedProperty login 是否为空。

试试@ManagedProperty(value = "#{Login}")

【讨论】:

  • 我不明白为什么它变成了 null ?因为它是 sessionScoped,这意味着当另一个 jsf 页面支持 bean 想要从中获取属性值时,应该没问题,对吧?另外,登录页面后会访问(业务服务)页面。
  • 查看已编辑,我认为 bean 为空,而不是 get_final_logged_ID()
猜你喜欢
  • 2018-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-17
相关资源
最近更新 更多