为什么Session bean的注入给出空指针异常?

问题描述:

我有一个非常简单的JSF 2.2(休眠4.3)应用程序,有2页。 第一页是必然低于会话bean login.xhtml为什么Session bean的注入给出空指针异常?

import javax.inject.Named; 
import java.io.Serializable; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.enterprise.context.SessionScoped; 
import javax.faces.application.FacesMessage; 

import javax.faces.context.FacesContext; 


@Named(value = "loginBean") 
@SessionScoped 
public class LoginBean implements Serializable { 

    /** 
    * Creates a new instance of LoginBean 
    */ 
    Company company; 

    private static final long serialVersionUID = 1520318172495977648L; 

    public String Login() { 
     CompanyHelper companyHelper = new CompanyHelper(); 
     company = companyHelper.Login(this.loginName, this.password); 
     if (company != null) { 
      return ""; 
     } else { 
      FacesMessage msg = new FacesMessage("Failed", "Wrong Usernames or password."); 
      msg.setSeverity(FacesMessage.SEVERITY_ERROR); 
      FacesContext.getCurrentInstance().addMessage(null, msg); 
      return ""; 
     } 
    } 


} 

它只是验证从数据库的用户名和密码,并返回公司物体

这势必会查看第二页delivery.xhtml豆。在这个bean内部,我注入了登录bean,但每次使用Company对象时都会返回null。但是,当我去login.xhtml,我发现公司对象不是null。 下面是交付bean。

import java.io.Serializable; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.annotation.PostConstruct; 
import javax.faces.model.SelectItem; 
import javax.inject.Named; 
import javax.faces.view.ViewScoped; 
import javax.inject.Inject; 


@Named(value = "deliveryBean") 
@ViewScoped 
public class DeliveryBean implements Serializable { 

    /** 
    * Creates a new instance of DeliveryBean 
    */ 
    @Inject 
    private LoginBean loginBean; 


    @PostConstruct 
    public void init() { 

     // returns null pointer expection 
     Logger.getLogger(LoginBean.class.getName()).log(Level.SEVERE, loginBean.company); 


    } 

    public String SendItem() { 
     // reutn null point expection 
     String personName=deliverRequest.setDeliverFrom(loginBean.company.getContactPersonName()); 
     return ""; 
    } 



} 

这里是pom.xml中

<dependencies> 
     <!-- https://mvnrepository.com/artifact/org.primefaces/primefaces --> 
     <dependency> 
      <groupId>org.primefaces</groupId> 
      <artifactId>primefaces</artifactId> 
      <version>6.1</version> 
     </dependency> 

     <dependency> 
      <groupId>javax</groupId> 
      <artifactId>javaee-web-api</artifactId> 
      <version>7.0</version> 
      <scope>provided</scope> 
     </dependency> 
     <!-- https://mvnrepository.com/artifact/javax.validation/validation-api --> 
     <dependency> 
      <groupId>javax.validation</groupId> 
      <artifactId>validation-api</artifactId> 
      <version>1.1.0.Final</version> 
     </dependency> 





     <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core --> 
     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-core</artifactId> 
      <version>4.3.11.Final</version> 
     </dependency> 


     <dependency> 
      <groupId>mysql</groupId> 
      <artifactId>mysql-connector-java</artifactId> 
      <version>5.1.40</version> 
     </dependency> 
     <dependency> 
      <groupId>org.slf4j</groupId> 
      <artifactId>slf4j-api</artifactId> 
      <version>1.7.12</version> 
     </dependency> 

我在Glassfish 4.1

+0

Java的代码惯例推荐以小写字母开头的方法名称:'方法应该是动词,大小写混合,首字母小写,每个内部单词的首字母大写。'http://www.oracle.com/ technetwork/JAVA/JavaSE的/文档/ codeconventions-135099.html#367 –

@Inject 
private LoginBean loginBean; 

注入方式的工作原理是首先将应用程序部署它在loginBean领域创建一个代理对象。 CDI不会立即创建或查找LoginBean实例。相反,它会一直等到您在loginBean字段中调用代理的方法。 CDI将此称为上下文参考 - 您将获得的实例取决于您要求的实例。

但你不调用一个方法:

loginBean.company.toString() 

您直接访问company场 - CDI无法拦截这一点。所以你从代理中得到一个无用的空值。

解决方案是不直接访问托管bean的字段。相反使company私人和创造一个getter:

public class LoginBean implements Serializable { 

private Company company; 

public Company getCompany() { 
    return company; 
} 

并称之为吸气的DeliveryBean