JSF页面以重定向循环结束

时间:2012-04-26 18:24:40

标签: java jsf loops redirect

我的浏览器总是返回一个重定向循环,我不知道为什么,看起来当我访问 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>

这是LoginController:

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>

2 个答案:

答案 0 :(得分:1)

发现问题,在top.html上,我在链接上调用loginController.logOut(),我不知道它为什么会自动执行,不等待我的点击,所以我更改了{ {1}} {1}} <a>

答案 1 :(得分:1)

模板文本中的EL表达式在渲染响应期间立即进行评估,并视为值表达式。即它们的返回值是作为HTML输出的一部分打印的。 “普通香草”HTML是也是模板文本。以下是

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

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

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

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

但是在那个方法中,你告诉JSF重定向到登录页面,因此它最终会进入无限循环。

这不是你真正想要的。您打算将其作为辅助bean操作方法调用。您应该使用完整的JSF UICommand组件,例如<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时,或者当您实际上不在操作方法中时才会被使用。