2017-09-17 73 views
1

我有一個非常簡單的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 –

回答

3
@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