Jsf 当我打开/home.xhtml时,不会调用映射到/home上的Servlet过滤器

Jsf 当我打开/home.xhtml时,不会调用映射到/home上的Servlet过滤器,jsf,login,servlet-filters,Jsf,Login,Servlet Filters,我是Java企业版新手。我开始学习一些YouTube视频,最近开始阅读我完成的第15章 我试着做我自己的过滤器 我没有使用JavaServlet类。因为我想使用JSF页面,据我所知,只有在JSF页面中使用托管bean是可能的,而Servlet类使用JSP。没关系 据我所知,登录过滤器的用途是: […]当您有多个页面 您想检查已登录的用户。而不是复制粘贴 在所有页面上都有相同的逻辑,您可以使用一个过滤器将其保存在单个页面中 地点 如我所知,当用户直接在浏览器中键入需要登录用户的页面的URL时,它

我是Java企业版新手。我开始学习一些YouTube视频,最近开始阅读我完成的第15章

我试着做我自己的过滤器

我没有使用JavaServlet类。因为我想使用JSF页面,据我所知,只有在JSF页面中使用托管bean是可能的,而Servlet类使用JSP。没关系

据我所知,登录过滤器的用途是:

[…]当您有多个页面 您想检查已登录的用户。而不是复制粘贴 在所有页面上都有相同的逻辑,您可以使用一个过滤器将其保存在单个页面中 地点

如我所知,当用户直接在浏览器中键入需要登录用户的页面的URL时,它非常有用,因此过滤器会将他重定向到登录页面,或者在他登录时继续

我搜索了任何简单的例子来学习,但没有找到。我将举一个简单的例子:

我有两个JSF页面
其中一个名为home.xhtml(需要登录用户)
另一个名为login.xhtml(如果未登录的用户寻求主页,则过滤器必须重定向到该过滤器)

login.xhtml:

  <h:form>
     <h:panelGrid columns="2">
     <h:outputLabel value="name:"/> <h:inputText value="#{user.name}"/>
     <h:outputLabel value="password:"/> <h:inputSecret value="#{user.password}"/>
     </h:panelGrid>
     <h:commandButton id="btn"  value="login" action="#{user.login()}"/>
  </h:form>
身份验证:

@ManagedBean
@SessionScoped
public class Authentication implements Serializable
{

   private boolean authenticated;

   public Authentication()
   {
      authenticated = false;
   }

   public boolean isLoggedIn()
   {
      return authenticated;
   }

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

}
登录过滤器:

@WebFilter(value = "/home")
public class LoginFilter implements Filter
{

   @Override
   public void init(FilterConfig filterConfig) throws ServletException
   {
      //throw new UnsupportedOperationException("Not supported yet.");
   }

   @Override
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException
   {
      HttpServletRequest req = (HttpServletRequest) request;
      Authentication auth = (Authentication) req.getSession().getAttribute("auth");

      if (auth != null && auth.isLoggedIn())
      {
         System.out.println("Filter is working");
         chain.doFilter(request, response);
      } else
      {
         System.out.println("Filter is working");
         HttpServletResponse res = (HttpServletResponse) response;
         res.sendRedirect(req.getContextPath() + "/login.xhtml");
      }
   }

   @Override
   public void destroy()
   {
      //throw new UnsupportedOperationException("Not supported yet.");
   }
}
面配置:

   <navigation-rule>
      <from-view-id>/login.xhtml</from-view-id>
      <navigation-case>
         <from-outcome>home</from-outcome>
         <to-view-id>/home.xhtml</to-view-id>
         <redirect/>
      </navigation-case>
      <navigation-case>
         <from-outcome>login</from-outcome>
         <to-view-id>/login.xhtml</to-view-id>
         <redirect/>
      </navigation-case>
   </navigation-rule>

/login.xhtml
家
/home.xhtml
登录
/login.xhtml
web.xml:

<context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <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>/faces/*</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>faces/login.xhtml</welcome-file>
    </welcome-file-list>

javax.faces.PROJECT_阶段
发展
Facesservlet
javax.faces.webapp.FacesServlet
1.
Facesservlet
/面孔/*
30
faces/login.xhtml

现在,当我在浏览器中键入home.xhtml页面的URL(在清除历史记录和cookies之后)时,假定它会将我重定向到登录页面。但它会返回主目录,名称为空:
Hello{user.name}。欢迎您
显示为
Hello。不客气


甚至
System.out.println(“过滤器正在工作”)不打印任何内容。

是否确实调用了筛选器?如果没有打印到
System.out
中,我想不会。问题可能是servlet映射

您指定了以下内容:

@WebFilter(value = "/home")
public class LoginFilter implements Filter {...}
我认为这只与url
/home
匹配。试着用
/*
/home*
(这是非常有限的,我不推荐)

另一件事:如果你得到
Hello{user.name}。欢迎您作为输出
,然后可能不会调用
FacesServlet
。这可能有两个原因:

  • 您使用了错误的映射。尝试使用
    /faces/home.xhtml
    /home.jsf
    调用页面。url取决于
    web.xml
    中的映射类型
  • web.xml
    中的
    FacesServlet
    配置不正确

  • 您确定已调用筛选器吗?如果没有打印到
    System.out
    中,我想不会。问题可能是servlet映射

    您指定了以下内容:

    @WebFilter(value = "/home")
    public class LoginFilter implements Filter {...}
    
    我认为这只与url
    /home
    匹配。试着用
    /*
    /home*
    (这是非常有限的,我不推荐)

    另一件事:如果你得到
    Hello{user.name}。欢迎您作为输出
    ,然后可能不会调用
    FacesServlet
    。这可能有两个原因:

  • 您使用了错误的映射。尝试使用
    /faces/home.xhtml
    /home.jsf
    调用页面。url取决于
    web.xml
    中的映射类型
  • web.xml
    中的
    FacesServlet
    配置不正确

  • Servlet 3.0中添加的注释@WebFilter。您的servlet版本是什么?servlet 3.0中添加的注释@WebFilter。您的servlet版本是什么?我将
    /home
    更改为
    /home*
    ,但过滤器不工作,并且
    系统输出
    不打印。但我将
    /home
    改为
    /*
    ,现在
    系统正在打印,但浏览器显示了我。因此,如何避免循环使用
    /*
    也会对
    login.xhtml
    调用过滤器,并一次又一次地重定向到同一页面。您可以手动检查过滤器中的
    login.xhtml
    (如
    req.getRequestURI().contains(“login.xhtml”)
    )以避免这种情况下的重定向。或者,您可以将所有需要登录的页面放在一个特殊路径中,如
    /secure
    ,并将筛选器映射到此路径
    /secure/*
    。好的,我添加了另一个检查,因此它变成
    if((auth!=null&&auth.isLoggedIn())| |(req.getRequestURI().contains(“login.xhtml”))
    。现在它可以正常工作了,当我键入
    home.xhtml
    时,它会重定向到
    login.xhtml
    (如预期的那样),或者如果我键入
    login.xhtml
    ,它会转到它(如预期的那样)。但是
    login.xhtml
    页面是完全空白的(没有
    标签
    没有
    输入文本
    没有
    按钮
    )。为什么不渲染它们!?。在
    web.xml
    中是否有
    FacesServlet
    的映射?我认为您没有映射,或者您在浏览器中使用了错误的URL来处理您的视图(请参见答案中的第1点)。看一看。根据您的映射,您必须使用
    /faces/home.xhtml
    和/faces/login.xhtml`(也用于重定向!!)调用页面。我将
    /home
    更改为
    /home*
    ,但过滤器不起作用,并且
    System.out
    不打印。但我将
    /home
    改为
    /*
    ,现在
    系统正在打印,但浏览器显示了我。因此,如何避免循环使用
    /*
    也会为
    login.xhtml
    调用过滤器,并重定向到同一pa
    @WebFilter(value = "/home")
    public class LoginFilter implements Filter {...}