簡體   English   中英

從JSF @ManagedBean遷移到CDI @Named后,多次調用的構造函數和提交的輸入值始終為null

[英]After migration from JSF @ManagedBean to CDI @Named, constructor called multiple times and submitted input values always null

編輯:評論部分解決了我的問題! 問題是我對Scopes使用了錯誤的導入。

我有一個簡單的JSF應用程序(登錄,從數據庫中提取數據,允許用戶編輯數據)。 它運行良好,我想更新代碼使用CDI(Weld),但我遇到了麻煩。 我正在關注/查看: http://docs.jboss.org/weld/reference/latest/en-US/html/example.htmlhttp://docs.jboss.org/weld/reference/latest/en-US/html/example.html沒有焊接的原始內容:

login.xhtml

<h:form id="inputForm">
    <h:panelGrid columns="2" cellpadding="5" cellspacing="1">
        <h:outputText id="nameDesc" value="Name"></h:outputText>
        <h:inputText id="nameInput" value="#{login.loginName}" binding="#{name}"></h:inputText>

        <h:outputText id="passwordDesc" value="Password"></h:outputText>
        <h:inputSecret id="passwordInput" value="#{login.password}" binding="#{password}"></h:inputSecret>

    </h:panelGrid>
    <h:commandButton value="Login" action="#{login.login(name.value, password.value)}"/>
</h:form>

LoginBean.java:

@ManagedBean(name="login")
@SessionScoped
public class LoginBean implements Serializable {
    private static final long serialVersionUID = 1L;
    @ManagedProperty(value="#{db}")
    private DatabaseBean db;
    private String password;
    private String loginName;
    // other stuff and functions

    public String getLoginName () {
       return loginName;
     }

    public void setLoginName (String name) {
       this.loginName = name;
    }

    public String getPassword () {
       return password;
    }

    public void setPassword (final String password) {
       this.password = password;
    }

    public void setDb(DatabaseBean db) {
        this.db = db;
    }

DatabaseBean.java:

@ManagedBean(name="db", eager=true)
@ApplicationScoped
public class DatabaseBean implements Serializable {
 @PostConstruct
    public void init() {
      //... connect to database etc
    }    

}

---------我試圖讓它與Weld一起運行(僅從上面進行更改以使其更短):-------- LoginBean.java,從@ManagedBean更改為@Named ,為DatabaseBean添加了@Inject

@Named("login")
@SessionScoped
public class LoginBean implements Serializable {
     // stuff 
         private @Inject DatabaseBean db;
}

DatabaseBean.java,從@ManagedBean更改為@Named:

@Named("db")
@ApplicationScoped
public class DatabaseBean implements Serializable {
}

LoginBean有一個函數:

public String login(String name, String password) {
    System.out.println("login called"+name);
    // other stuff

}

在我的第二個實現(我嘗試使用Weld的那個)中,print被調用一次:“login called”,用戶名為空(我用name.IsEmpty()檢查了它)。

我也嘗試過構造函數注入它:

loginBean.java

@Inject
public LoginBean(DatabaseBean db) {
    System.out.println("constructor");
    this.db = db;
}

當我這樣做時,我得到了很多“構造函數”打印,因此它被調用了好幾次,但我不明白為什么 - 我想這是問題,但只有一個LoginBean實例獲取輸入(用戶名和密碼)然后由於某種原因創建了許多新的。 這是為什么?

我使用Eclipse和Tomcat8來運行它。 謝謝你的閱讀!

托管bean構造函數多次調用

在生成/創建增強的子類/代理時,CDI可能比預期更頻繁地調用構造函數。 另請參見Field.get(obj)返回注入的CDI托管bean上的所有空值,而手動調用getter則返回正確的值 只是不要記錄構造函數調用,它只會讓自己迷惑。 @PostConstruct是唯一有趣的方法。


print被調用一次:“login called”,用戶名為空(我用name.IsEmpty()檢查了這個)。

至於調用action方法時表單輸入值為null的具體問題,因此@SessionScoped CDI托管bean似乎在每次訪問時都會重新創建,這與@Dependent作用域bean的行為相匹配。 當找不到有效的CDI托管bean作用域時,這是默認作用域。 另請參見JSF 2應用程序中的默認Managed Bean Scope是什么?

這反過來表明您從錯誤的包中導入了@SessionScoped 確保它來自javax.enterprise.context包,而不是來自例如javax.faces.bean JSF托管bean作用域無法識別為有效的CDI托管bean作用域。

import javax.inject.Named;
import javax.enterprise.context.SessionScoped;

@Named("login")
@SessionScoped
public class LoginBean implements Serializable {
    // ...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM