2

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

这就是我的工作方式,基于一些谷歌搜索。

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

主控制器;家庭控制器;登录控制器;

我将在没有 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 我检查会话状态,如果错误重定向到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因为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 过滤器。但那是另一回事了。

于 2012-04-26T16:05:15.283 回答