1

編集:さて、何が起こっているかを確認するためにいくつかの console.writes を設定しようとしました...ナビゲーション時にログアウトスクリプトが呼び出されるようです。しかし、ログアウトボタン以外では呼び出しません。

ここに私のテンプレートコードがあります:

<div class="navbar">
    <div class="navbar-inner">
        <ul class="nav">
            <li class="active"><a href="#{root}index.xhtml">Home</a></li>
            <li><a href="#{root}races/list.xhtml">Races</a></li>
            <li><a href="#{root}horses/list.xhtml">Horses</a></li>
            <h:panelGroup rendered="#{memberController.logged == true}">
                <li><a href="#{root}profile/history.xhtml">History</a></li>
                <li><a href="#" onclick="#{memberController.logout()}">Logout</a></li>
            </h:panelGroup>
            <h:panelGroup rendered="#{memberController.logged == false}">
                <li><a href="#{root}users/login.xhtml">Login</a></li>
                <li><a href="#{root}users/register.xhtml">Create Account</a></li>
            </h:panelGroup>
        </ul>
    </div>
</div>

オリジナルメッセージ:

学校のプロジェクト (Java EE) 用の Web サイトを作成しています。これは夜の学校で、1学期しか習っていないので、私のやり方が最善ではないことがわかるかもしれません:)

開始するには、ログイン機能を作成しようとしていますが、何百行ものセキュリティ コードの代わりに、単純なセッション スコープのメンバー オブジェクトを使用できます。

だからここに私のクラスのいくつかがあります:

メンバー クラス:

@Entity
@Table(name = "members")
public class Member implements Serializable {
    //+ Getters, setters, HashCode and equals

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    private long id;
    private double money;

    @NotNull(message = "Username cannot be null")
    @Size(min = 4, message = "Username should be of minimum 4 characters")
    private String userName;

    @NotNull(message = "Password cannot be null")
    @Size(min = 4, message = "Password should be of minimum 4 characters")
    private String password;

    @PostPersist
    private void initDefault() {
        this.money = 500;
    }
}

MemberBean クラス:

@Stateless
public class MemberBean {

    @PersistenceContext(unitName="HorseRacingPU")
    private EntityManager em;

    public Member getMember(long id){
        return em.find(Member.class, id);
    }

    public Member getMember(String username, String password){
        TypedQuery<Member> q = em.createQuery("SELECT u FROM Member u WHERE u.userName=?1 AND u.password=?2", Member.class);
        q.setParameter(1, username);
        q.setParameter(2, password);
        return q.getSingleResult();
    }

    public List<Member> getAllMembers(){
        TypedQuery<Member> q = em.createQuery("SELECT u FROM Member u", Member.class);
        return q.getResultList();
    }

    public Member addOrUpdateMember(Member u){
        Member original = em.find(Member.class, u.getId());
        if(original == null){
            em.persist(u);
            return u;
        }else{
            return em.merge(u);
        }
    }

    public Member deleteMember(long id){
        Member original = em.find(Member.class, id);
        if(original != null){
            em.remove(original);
        }
        return original;
    }
}

MemberController クラス:

@SessionScoped
public class MemberController implements Serializable {

    @EJB
    private MemberBean bean;
    private String username;
    private String password;
    private Member member;
    private boolean logged = false;
// + their getters and setters

    public List<Member> getAllMembers() {
        return bean.getAllMembers();
    }

    public String login() {
        member = bean.getMember(username, password);
        if (member != null) {
            logged = true;
            return "/races/list.xhtml?faces-redirect=true";
        }
        return "/users/login.xhtml?faces-redirect=true";
    }

    public String logout() {
        FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
        return "/index.xhtml?faces-redirect=true";
    }

    public void checkLogin(ComponentSystemEvent e) {
        if (!logged) {
            FacesContext context = FacesContext.getCurrentInstance();
            ConfigurableNavigationHandler handler = (ConfigurableNavigationHandler) context.getApplication().getNavigationHandler();
            handler.performNavigation("/users/login.xhtml?faces-redirect=true");
        }
    }

    public Member getMember() {
        return member;
    }

    public void submit() {
        bean.addOrUpdateMember(member);
    }
}

私が得ている主なエラーは次のとおりです。

情報: 応答をリセットしようとしてエラーを処理中に例外が発生しました。

より具体的な詳細エラーがここにあります: http://pastebin.com/h5nTNnes

何が起こるかというと、ログインすると、すべてがうまく機能します。別の URL に移動した瞬間(/races/list に転送された後)、ログアウトされます。checkLogin() を使用すると、エラー自体が表示されます。

<f:event type="preRenderView" listener="#{memberController.checkLogin}" />

これが関連しているかどうかはわかりませんが、デモ データなしで (または間違った資格情報で) ログインすると、評価例外が発生し、エンティティを取得できませんでした。詳細はこちら: http://pastebin.com/Tv9mQ1K9

これは何でしょうか?私は今3日間頭を悩ませていますが、どこにも問題が見つからないようです.

4

1 に答える 1

1

これ、

<li><a href="#" onclick="#{memberController.logout()}">Logout</a></li>

正しくありません。

このonclick属性は、JavaScript ハンドラーを参照する必要があります。例alert('peek-a-boo');。JSF/EL はこれをプレーンなバニラ文字列として扱い、logout()メソッドが何らかの JavaScript コードを返すことを期待しStringます。これは、HTML の結果にインライン化する必要があります。メソッドが実際に を返しalert('peek-a-boo');た場合、最終結果 (ブラウザで右クリックして[ソースを表示]を表示) は次のようになります。

<li><a href="#" onclick="alert('peek-a-boo');">Logout</a></li>

ただし、特定のケースでは、実際にログアウトを実行し、文字列値を返しています/index.xhtml?faces-redirect=true。したがって、生成されたHTMLは最終的に

<li><a href="#" onclick="/index.xhtml?faces-redirect=true">Logout</a></li>

これは無効な JS コードです。しかし、それは大きな問題ではありません: ユーザーはリンクをクリックせずにログアウトされました!

代わりに、完全な JSF コマンド コンポーネントが必要です。例<h:commandLink>

<li><h:form><h:commandLink value="Logout" action="#{memberController.logout()}"/></h:form></li>

メソッドはこの方法で、リンクが実際にクリックされたときにのみ呼び出されます。これはまさに必要なものです。

于 2013-01-16T17:10:12.097 に答える