0

Java EE アプリケーションでログインを処理するために、セッション スコープのマネージド Bean を使用しています。ユーザーを認証すると、ユーザー オブジェクトがこのセッション Bean に保存されます。ただし、ページを更新すると、セッション Bean の値が表示されなくなります。

コードをデバッグしていたところ、セッション スコープのマネージド Bean のコンストラクターがページの更新時に再度呼び出され、ユーザー オブジェクトが新しいユーザーで初期化されました。セッションで保持する必要があるため、これは通常の動作ではないと思います。

パラメータやログイン方法など、ログインマネージド Bean の一部を掲載しています。基本的に、enteredEmail とenteredPassword は、ログイン フォームに入力されたデータを表します。認証が成功すると、loggedIn ブール値が true に変わり、ログインしているユーザー オブジェクトが checkedUser 変数に格納されます。

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean
@SessionScoped
public class LoginController  implements Serializable {

@EJB
private LoginSessionBean loginSessionBean;
@EJB
private LecturerFacade lecturerFacade;

private Lecturer checkedUser;
private String enteredEmail;
private String enteredPassword;
private boolean loggedIn;





/** Creates a new instance of loginController */
public LoginController() {
   loggedIn = false;
   checkedUser = new Lecturer();
}
public String login(){
    RequestContext context = RequestContext.getCurrentInstance();
    FacesMessage msg = null;

    this.setCheckedUser(lecturerFacade.findLecturerByEmail(enteredEmail));

    if(loginSessionBean.checkPassword(checkedUser, enteredPassword))
    {
        loggedIn = true;
        msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Welcome", checkedUser.getFirstName()+ " " + checkedUser.getLastName());



        FacesContext.getCurrentInstance().addMessage(null, msg);
        context.addCallbackParam("loggedIn", loggedIn);



    }
    return "Index";

上記のマネージド Bean が使用する 2 つの EJB も掲載しています。lecturerFacade は、入力された電子メールでユーザー オブジェクトを取得し、loginSessionBean はパスワードをチェックします。

@Stateless
public class LecturerFacade extends AbstractFacade<Lecturer> {
@PersistenceContext(unitName = "EffectinetWebPU")
private EntityManager em;

Logger logger = Logger.getLogger("MyLog");
FileHandler fh;


protected EntityManager getEntityManager() {
    return em;
}

public LecturerFacade() {
    super(Lecturer.class);
}

public Lecturer findLecturerByEmail(String email) {
    try {
        return (Lecturer) this.getEntityManager().createQuery("SELECT l FROM Lecturer l WHERE l.email = :email").setParameter("email", email).getSingleResult();
    } catch (NoResultException e) {
        System.err.println("Caught NOResultException: "+  e.getMessage());
        return null;
    } catch (NonUniqueResultException e) {
        System.err.println("Caught NonUniqueResultException: "+  e.getMessage());
        return null;
    } catch (IllegalStateException e) {
        System.err.println("Caught IllegalStateException: "+  e.getMessage());
        return null;
    }
}

_

@Stateless

public class LoginSessionBean {

// Add business logic below. (Right-click in editor and choose
// "Insert Code > Add Business Method")
@PersistenceContext(unitName = "EffectinetWebPU")
private EntityManager em;

protected EntityManager getEntityManager() {
    return em;
}

public void setEntityManager(EntityManager em) {
    this.em = em;
}



public boolean checkPassword(Lecturer user, final String enteredPassword) {
    if (user.getPassword().equals(enteredPassword)) {
        return true;
    } else {
        return false;
    }
}

}

誰かが何がうまくいかないのかについて何か提案があれば教えてください

アプリケーションサーバーとしてglassfish 3.1を使用し、JSFライブラリとしてPrimefacesを使用しています。また、javax.enterprise からではなく、適切なパッケージから sessionScoped アノテーションをチェックしてインポートしました...

4

2 に答える 2

6

したがって、あなたの問題はここにあります:

<p:menuitem value="Logout" ... onclick="#{loginController.logout()}"/>

この属性は、エンドユーザーが要素をクリックしたときに Web ブラウザーで実行されるJavaScriptハンドラー関数をonclick表す必要があります。何かのようなもの

onclick="alert('You have clicked this element!')"

このonclick属性は も受け入れるためValueExpression、それに応じて JSF/EL にその値を自動生成させることもできます。

onclick="#{bean.onclickFunction}"

public String getOnclickFunction() {
    return "alert('You have clicked this element!')";
}

したがって、ページがレンダリングされるときにすべての EL が評価されます。あなたの特定のケースではlogout()、ELが評価されるたびにメソッドが呼び出されるため、ページがレンダリングされるたびにセッションを無効にしています!

MethodExpressionlike<h:commandLink action>を取る属性にバインドする必要が<h:commandButton action>あり、この特定のケースでは<p:menuitem action>.

<p:menuitem value="Logout" ... action="#{loginController.logout()}"/>

これは、基本的な HTML と JavaScript の概念を理解し、JSF が最終的に HTML/CSS/JS を生成することを念頭に置くことで理解できます。WebブラウザでJSFページを開き、右クリックしてソースを表示すると実現します。

于 2012-05-28T13:43:01.970 に答える
0

さて、今日はなんとか解決できました。これが問題でしたが、理由は説明できません。

Primefaces 3.2をJSFライブラリとして使用していたので、これがインデックスページのメインメニューでした。

<h:form>
        <p:menubar >
            <p:menuitem id="registerLink" value="Register" rendered="#{!loginController.loggedIn}" onclick="registerDialog.show()" /> 

            <p:menuitem id="loginLink" value="Login" rendered="#{!loginController.loggedIn}" onclick="loginDialog.show()" />

            <p:submenu label="Units" rendered="true"> 
                <p:menuitem id="addNew" value="Add New" onclick="createUnitDialog.show()" />

                <p:menuitem id="myUnits" value="My Units" onclick="" />
            </p:submenu>        

            <p:menuitem id="results" value="Results/Statistics" rendered="#{loginController.loggedIn}" onclick=""/>

            <p:menuitem id="profile" value="My Profile" rendered="#{loginController.loggedIn}" onclick=""/>

            <p:menuitem id="logout" value="Logout" rendered="#{loginController.loggedIn}" onclick="#{loginController.logout()}"/>

        </p:menubar>
    </h:form>

コード全体にブレークポイントを設定した後、管理対象Beanを破棄することになっているlogout()メソッドが、ページが更新されるたびに呼び出されることを発見しました。ログアウトメニュー項目がクリックされたときに呼び出されるはずなので、なぜこれが起こったのかわかりません。

しかし、を変更した後onclick="#{loginController.logout()}action="#{loginController.logout()}問題は解決しました。

Primefacesのドキュメントを確認しましたが、この動作が説明されていませんでした

于 2012-05-28T12:27:35.667 に答える