繁体   English   中英

尝试在JSF中使用Servlet过滤器登录时出现无限循环

[英]Infinite loop when trying to login using Servlet Filter in JSF

我正在尝试使用JSF和servlet过滤器创建登录应用程序,但是当用户登录时什么也没发生。 它再次重定向到登录页面。

这是项目目录: 在此处输入图片说明

这是web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" 
         xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <filter>
        <filter-name>LoginFilter</filter-name>
        <filter-class>javaeetutorial.guessnumber.filters.LoggedInFilter</filter-class>
    </filter>
    <!-- Set the login filter to secure all the pages in the /secured/* path of the application  -->
    <filter-mapping>
        <filter-name>LoginFilter</filter-name>
        <url-pattern>/secured/*</url-pattern>
    </filter-mapping>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>greeting.xhtml</welcome-file>
    </welcome-file-list>
</web-app>

这是LoggedInFilter.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package javaeetutorial.guessnumber.filters;

import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javaeetutorial.guessnumber.TestBean;

/**
 *
 * @author salih
 */
public class LoggedInFilter implements Filter {

    FilterConfig fc;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        fc = filterConfig;
        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        Enumeration<String> t = ((HttpServletRequest) request).getSession().getAttributeNames();

        while(t.hasMoreElements()) { System.out.println(t.nextElement().toString());}
        TestBean loginBean = (TestBean) ((HttpServletRequest) request).getSession().getAttribute("testBean");

        // For the first application request there is no loginBean in the session so user needs to log in
        // For other requests loginBean is present but we need to check if user has logged in successfully
        if (loginBean == null || !loginBean.isLoggedIn()) {
            String contextPath = ((HttpServletRequest) request).getContextPath();
            ((HttpServletResponse) response).sendRedirect(contextPath + "/login.xhtml");
        }

        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}

这是TestBean.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package javaeetutorial.guessnumber;

import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedProperty;
import javax.faces.context.FacesContext;
import javax.inject.Named;

/**
 *
 * @author salih
 */
@Named
@SessionScoped
public class TestBean implements Serializable {

    private boolean loggedIn;
    private String username;
    private String password;


    private NavigationBean navigationBean = new NavigationBean();

    private static final String[] users = {"anna:qazwsx", "kate:123456"};

    public String getUsername() {
        return username;
    }

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

    public String getPassword() {
        return password;
    }

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

    public boolean isLoggedIn() {
        return loggedIn;
    }

    public void setLoggedIn(boolean loggedIn) {
        this.loggedIn = loggedIn;
    }

    public String doLogin() {
        // Get every user from our sample database :)
        for (String user : users) {
            String dbUsername = user.split(":")[0];
            String dbPassword = user.split(":")[1];

            // Successful login
            if (dbUsername.equals(username) && dbPassword.equals(password)) {
                loggedIn = true;
                return navigationBean.redirectToWelcome();
            }
        }

        // Set login ERROR
        FacesMessage msg = new FacesMessage("Login error!", "ERROR MSG");
        msg.setSeverity(FacesMessage.SEVERITY_ERROR);
        FacesContext.getCurrentInstance().addMessage(null, msg);

        // To to login page
        return navigationBean.toLogin();

    }
}

这是login.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"htth://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"     
      xmlns:h="http://java.sun.com/jsf/html">

    <h:head>
        <title>Login form</title>
    </h:head>
    <h:body>
        <h3>Login here</h3>
        <h:form id="login-form">
           <h:outputText value="username:"/>
           <h:inputText value="#{testBean.username}" id="username"/>
           <br/>
           <h:outputText value="password:"/>
           <h:inputSecret value="#{testBean.password}" id="password"/>
           <br/>
           <h:commandButton id="button" value="Login" action="#{testBean.doLogin}"/>
           <br/>
           <h:commandLink action="#{navigationBean.redirectToInfo}" value="Info page"/>
           <br/>
           <h:messages />
           <br/>
        </h:form>
    </h:body>
</html>

您正在将JSF托管Bean /概念与CDI托管Bean混合使用。

首先,您忽略了要指定的容器,但是我将为普通的servlet容器写一个答案,为启用CDI的Java应用程序服务器(例如TomEE / Wildfly / Glassfish)写一个答案。

使用@Named@SessionScoped但请确保您具有正确的@SessionScoped。 javax.enterprise.context是程序包名称。 如果您使用JSF中的SessionScoped,则bean将具有依赖范围,这是错误的。

现在,卸下过滤器并使用测试页进行快速测试。 使用<h:inputText /><h:commandButton> (均在<h:form> )设置一个字段。 确保F5之后的值仍然存在,并因此成功@SessionScoped.

如果它不起作用,请确保您正在使用CDI 1.1或已在文档中相应地包含beans.xml。

最后使用

@Inject
private TestBean testBean;

或者,如果您拥有像Tomcat或Jetty这样的普通容器,则需要使用Deltaspike Core,然后使用: TestBean testBean = BeanProvider.getContextualReference(TestBean.class, false);

祝好运

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM