2016-04-01 8 views
4

編集:コメントセクションが私の問題を解決しました!問題は、Scopesに誤ったインポートを使用していたことでした。JSF @ManagedBeanからCDI @ Namedに移行した後、コンストラクタが複数回呼び出され、入力値が常にNULLに設定されました

私はシンプルなJSFアプリケーション(ログイン、データベースからのプル・データ、ユーザーによるデータの編集を許可)を持っています。うまくいき、CDI(Weld)を使用するようにコードを更新したいが、問題がある。溶接なしhttp://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

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

DatabaseBean.javaため@Injectを加え、@ManagedBeanから@Namedに変更:

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

} 

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

LoginBean機能を有しています

2回目の実装(Weldを使用しようとする)では、プリントは一度呼び出されます。「ログインが呼び出されました」というユーザー名は空です(これはname.IsEmpty()でチェックされています)。

私はまた、コンストラクタでそれを注入しようとしている:

loginBean.java

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

私はこれを行うと、私はそれが複数回呼ばれて、「コンストラクタ」プリントの多くを得るが、私理由は分かりません - これは問題だと思いますが、LoginBeanの1つのインスタンスだけが入力(ユーザー名とパスワード)を取得し、何らかの理由で新しいものが多数作成されます。何故ですか?

EclipseとTomcat8を使用して実行します。 読んでいただきありがとうございます!生成中

+1

「@ SessionScoped」では正しいものを使用してください。 –

+0

こんにちは、返信いただきありがとうございます!私のsessionscoped:import javax.faces.bean.SessionScoped; – Lomtrur

+1

CDIを使用する場合は、JSFスコープではなく** CDIスコープを使用する必要があります。 –

答えて

2

管理Beanコンストラクタと呼ばれる複数回

CDIが向上サブクラス/プロキシを作成/予想よりも多くのコンストラクタを呼び出すことができます。 Field.get(obj) returns all nulls on injected CDI managed beans, while manually invoking getters return correct valuesも参照してください。コンストラクタ呼び出しをログに記録しないでください。混乱するだけです。 @PostConstructが唯一興味深い方法です。


印刷が一度呼び出されます:「ログインはいわゆる」、およびユーザ名が空である(私は名前でこれを確認しました。IsEmpty())。アクションメソッドが呼び出されたときにフォームの入力値がnullという具体的な問題としては

、したがって@SessionScoped CDIは、一見すべてのアクセスに再作成された豆を管理、これは@Dependentスコープ豆の挙動と一致します。これは、有効なCDI管理Beanスコープが見つからない場合のデフォルトスコープです。関連項目What is the default Managed Bean Scope in a JSF 2 application?

これは間違ったパッケージから@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 { 
    // ... 
} 
関連する問題