1

我的浏览器总是返回一个重定向循环,我不知道为什么,看起来当我访问login.html时它正在调用我的一些方法。

这是 login.html 文件:

<ui:composition
    template="/templates/master.xhtml"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html">
    <ui:define name="body">

        <div class="container-fluid">
            <div class="row-fluid">
                <div class="span12">
                    <h:form class="form-horizontal">
                        <fieldset>
                            <legend>Bem vindo a Sergio's</legend>
                            <br/>
                            <p>Preencha os campos abaixo para entrar no sistema.</p>
                            <div class="control-group">
                                <label class="control-label" for="user">Usuário</label>
                                <div class="controls">
                                    <h:inputText required="true" id="user" value="#{loginController.username}" class="input-medium" />
                                    <h:message for="user" />
                                </div>
                            </div>
                            <div class="control-group">
                                <label class="control-label" for="password">Senha</label>
                                <div class="controls">
                                    <h:inputSecret required="true" id="password" value="#{loginController.password}" class="input-medium"/>
                                    <h:message for="password" />
                                </div>
                            </div>
                            <div class="form-actions">
                                <h:commandButton action="#{loginController.login()}" class="btn btn-primary" value="Entrar"/>
                            </div>
                        </fieldset>
                    </h:form>
                    <h:messages/>
                </div>
            </div>
        </div>

    </ui:define>
</ui:composition>

这是登录控制器:

package com.erp3.gui.controllers;

import java.io.IOException;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;

@ManagedBean
public class LoginController {

    public Boolean isLoggedIn = false;
    private String username;
    private String password;
    private FacesMessage facesMessage;
    public ExternalContext externalContent;

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Boolean getIsLoggedIn() {
        return isLoggedIn;
    }

    public void setIsLoggedIn(Boolean isLoggedIn) {
        this.isLoggedIn = isLoggedIn;
    }

    public void login() throws IOException {
        if (this.getUsername().equals("daniel") && this.getPassword().equals("123")) {
            this.isLoggedIn = true;
            externalContent = FacesContext.getCurrentInstance().getExternalContext();
            externalContent.getSessionMap().put("loginController", this);
            externalContent.redirect(externalContent.getRequestContextPath() + "/views/home.html");
        } else {
            this.isLoggedIn = false;
            facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Usuário ou senha inválida.", username);
            FacesContext.getCurrentInstance().addMessage(null, facesMessage);
            externalContent.redirect(externalContent.getRequestContextPath() + "/views/login.htm");
        }
    }

    public void logOut() throws IOException {
        externalContent = FacesContext.getCurrentInstance().getExternalContext();
        externalContent.getSessionMap().remove("loginController");
        externalContent.redirect(externalContent.getRequestContextPath() + "/views/login.html");
    }

}

我有一个 master.html 是我的模板,它正在调用一个带有以下内容的 top.html:

<ui:composition
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:ui="http://java.sun.com/jsf/facelets">
    <div class="navbar navbar-fixed-top">
        <div class="navbar-inner">
            <div class="container-fluid">
                <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </a>
                <a class="brand" href="#">Project name</a>
                <div class="btn-group pull-right">
                    <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
                        <i class="icon-user"></i>
                        <span class="caret"></span>
                    </a>
                    <ul class="dropdown-menu">
                        <li><a href="#">Conta</a></li>
                        <li class="divider"></li>
                        <li><a href="#{loginController.logout}">Sair</a></li>
                    </ul>
                </div>
                <div class="nav-collapse">
                    <ul class="nav">
                        <li class="active"><a href="#">Home</a></li>
                        <li><a href="#about">About</a></li>
                        <li><a href="#contact">Contact</a></li>
                    </ul>
                </div>
            </div>
        </div>
    </div>
</ui:composition>
4

2 回答 2

1

发现了问题,在我的top.html,我正在调用loginController.logOut()一个链接,但我不知道它为什么会自动执行,没有等待我的点击,所以我更改了<a>for<h:commandLink/>

于 2012-04-26T18:59:26.680 回答
1

模板文本中的EL 表达式在呈现响应期间立即被评估并被视为值表达式。即它们的返回值被打印为 HTML 输出的一部分。“Plain vanilla” HTML也是模板文本。所以以下

<li><a href="#{loginController.logOut()}">Sair</a></li>

基本上会调用该方法,href在渲染响应期间将其返回值打印为 URL。然后生成的 HTML 是:

<li><a href="">Sair</a></li>

(是的,这href是空的,因为您实际上返回void而不是有效String)

但是在该方法中,您告诉 JSF 重定向到登录页面,因此它最终陷入无限循环。

这不是你真正想要的。您打算将其作为支持 bean 操作方法调用。您应该UICommand为此使用完全值得的 JSF 组件,例如<h:commandLink>.

<li><h:form><h:commandLink value="Sair" action="#{loginController.logOut()}" /></h:form></li>

这样,您还可以更改logOut()方法以返回完全值得的导航结果:

public String logOut() {
    FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
    return "/views/login.html?faces-redirect=true";
}

应该仅在ExternalContext#redirect()您想要重定向到非 JSF URL 时使用,或者当您实际上不在操作方法中时使用。

于 2012-04-26T19:05:54.837 回答