2

Faces で JSF を確認するためのログイン例を作成しています。PHP のバックグラウンドがあるため、多くの問題を抱えています。

これは、いくつかのグーグル検索に基づいて、私がどのように働いているかです。

3 つのコントローラーを含むフォルダーがあります。

メインコントローラ; ホームコントローラー; LoginController;

読みやすくするために、get と set なしでそれぞれの bu を示します。

メインコントローラー:

package com.erp3.gui.controllers;

import javax.faces.context.FacesContext;

public class MainController {

    public LoginController loginController;

    public MainController() {
        this.checkUserSession();
    }

    public String checkUserSession() {
        loginController = (LoginController) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("loginController");
        if (!loginController.getIsLoggedIn()) {
            return "login.html";
        } else {
            return null;
        }
    }
}

ホームコントローラー:

package com.erp3.gui.controllers;

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

@ManagedBean
public class HomeController extends MainController {

    public String username;

    public HomeController() {
        super();
    }
}

ログインコントローラー:

package com.erp3.gui.controllers;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;

@ManagedBean
public class LoginController {

    public Boolean isLoggedIn = false;
    private String username;
    private String password;
    private FacesMessage msg;

    public String login() {

        if (this.getUsername().equals("daniel") && this.getPassword().equals("123")) {
            this.isLoggedIn = true;                 
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("loginController", this);
            return "home.html";
        } else {
            this.isLoggedIn = false;
            msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Usuário ou senha inválida.", username);
            FacesContext.getCurrentInstance().addMessage(null, msg);
            return "login.html";
        }
    }

    public String logOut() {
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("loginController");
        return "login.html";
    }
}

したがって、セッションを作成するこの方法を見つけたいくつかのページを読んで、それが正しい場合はノーしないでください:

FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("loginController", this);

何が起こるかというと、HomeController でセッション ステータスをチェックし、false の場合はlogin.xhtmlにリダイレクトします。

別のこととして、ログインすると、home.xhtmlにリダイレクトされますが、URL はまだ有効で、login.xhtml変更すると次のhome.xhtml美しいエラーが返されます。

Cant instantiate class: com.erp3.gui.controllers.HomeController. 

また、 home.xhtmlファイルを呼び出すと、HomeControllerまたは Java が単純に home.xhtml をロードすることを知りたいですか?

4

1 に答える 1

0

文字列の結果を返すことによるナビゲーションは、コンストラクターではなく、 のUICommandようなコンポーネントによって呼び出される実際のアクション メソッドでのみ可能です。<h:commandButton>

new HomeController()その例外は、基本的に失敗したことを伝える一般的な例外です。これには、スタックトレースのさらに下に根本原因があるはずです。おそらく、NullPointerExceptionだからloginControllerですかnull?いずれにせよ、スタックトレースの最下位の例外である根本原因は、探すべき最も重要な例外です。これを覚えておいてください。

どちらの問題も、次の方法で修正できます。

public class MainController {

    public MainController() throws IOException {
        this.checkUserSession();
    }

    public void checkUserSession() throws IOException {
        ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
        LoginController loginController = (LoginController) ec.getSessionMap().get("loginController");

        if (loginController == null || !loginController.getIsLoggedIn()) {
            ec.redirect(ec.getRequestContextPath() + "/login.html");
        }
    }

}

ただし、このアプローチには技術的な問題があります。応答がコミットされてからリダイレクトを送信するのは遅すぎます。Beanは、応答の一部がクライアントに送信された時点でのみ構築できます。むしろ、コンテナ管理の認証、または少なくともサーブレット フィルタを見てください。しかし、それは別の話です。

于 2012-04-26T16:05:15.283 に答える