JSF登录会话和重定向

时间:2012-04-26 15:38:30

标签: jsf login

我正在创建一个登录示例来查看带有Faces的JSF,我有一个PHP背景,所以我有很多困难。

根据谷歌搜索,这就是我的工作方式。

我有一个包含3个控制器的文件夹:

MainController; HomeController的; 的LoginController;

我会在没有get的情况下显示每个bu,并设置为更容易阅读。

MainController:

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;
        }
    }
}

HomeController中:

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();
    }
}

的LoginController:

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上我会检查会话状态,如果错误重定向到 login.xhtml

另一件事是,当我登录时,我已重定向到 home.xhtml ,但网址仍在login.xhtml上,当我将其更改为{{1}时它给我带来了这个美丽的错误:

home.xhtml

我还想知道,当我调用 home.xhtml 文件时,它会加载 HomeController ,或者只是加载 home.xhtml

1 个答案:

答案 0 :(得分:0)

通过返回字符串结果进行导航只能在实际操作方法中实现,这些方法由UICommand组件调用,如<h:commandButton>,而不是构造函数。

该异常是一般异常,基本上告诉new HomeController()失败。这反过来又会导致堆栈跟踪中的根本原因。可能是NullPointerException,因为loginControllernull?无论如何,堆栈跟踪中最底层异常的根本原因是要查找的最重要的异常。记住这一点。

这两个问题都可以通过以下方式解决:

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 。而是查看容器管理的身份验证或至少在servlet过滤器上。但这是另一个故事。