从 servlet 过滤器重定向到 jsf 会返回未呈现为 html 的实际 jsf 代码

Posted

技术标签:

【中文标题】从 servlet 过滤器重定向到 jsf 会返回未呈现为 html 的实际 jsf 代码【英文标题】:redirecting from a servlet filter to jsf returns the actual jsf code not rendered to html 【发布时间】:2012-06-23 17:29:39 【问题描述】:

下面是我的代码;

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

import java.io.IOException;
import javax.faces.application.NavigationHandler;
import javax.faces.context.FacesContext;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;


@WebFilter("/faces/*")
public class AuthenticationFilter implements Filter 

    @Override
    public void init(FilterConfig config) throws ServletException 
        // If you have any <init-param> in web.xml, then you could get them
        // here by config.getInitParameter("name") and assign it as field.
    

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException 
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        HttpSession session = request.getSession(false);

        String pageRequested = request.getRequestURI().toString(); 
        //try
        //FacesContext fctx = FacesContext.getCurrentInstance();
        //NavigationHandler myNav = fctx.getApplication().getNavigationHandler();



         if(session==null)       
               session = request.getSession(true); // will create a new session     
               response.sendRedirect("Login.xhtml");       
               //myNav.handleNavigation(fctx, null, "Login");
         else if(session==null && pageRequested.contains("Login.xhtml"))       
                //  session.getAttribute("user");     
                chain.doFilter(request, response); // continue filtering       
         else if((session.getAttribute("user")== null) && (!pageRequested.contains("Login.xhtml")))          
             response.sendRedirect("Login.xhtml");
             //myNav.handleNavigation(fctx, null, "Login");
         else 
             chain.doFilter(request, response);
         
        //catch(Exception e)
        //    System.out.println("Error :"+ e);
        //
        /*if ((((HttpServletRequest) req).getSession().getAttribute("user") == null)) 
            FacesContext fctx = FacesContext.getCurrentInstance();
            NavigationHandler myNav = fctx.getApplication().getNavigationHandler();
            myNav.handleNavigation(fctx, null, "Login");
            //response.sendRedirect(request.getContextPath() + "/Login.xhtml"); // No logged-in user found, so redirect to login page.
         else 
            chain.doFilter(req, res); // Logged-in user found, so just continue request.
        */
    

    @Override
    public void destroy() 
        // If you have assigned any expensive resources as field of
        // this Filter class, then you could clean/close them here.
    


如果我使用 FacesContext.getCurrentInstance(),会发生 java.lang.Nullpointer 异常; 如果我使用 response.sendRedirect("Login.xhtml");它显示一个空白页面,如果我查看源代码,我可以在 jsf 中看到 Login.xhtml 的源代码。它不会呈现为 html..

我想要做的是:如果用户没有登录并访问任何页面,则将他发送到 Login.xhtml,如果用户在 Login.xhtml 上,则向他显示要登录的页面。

请帮忙..

【问题讨论】:

你能在没有过滤器的情况下呈现登录页面吗?我会首先确保没有过滤器 login.xhtml 正确呈现。如果没有过滤器,login.xhtml 也没有渲染,那么,faces-config.xml 中的 url 映射很可能有问题 【参考方案1】:

重定向到与 FacesServlet 映射匹配的 URL。显然它映射到/faces/* 而不是*.xhtml。然后重定向到faces/Login.xhtml

这里重写,简化了逻辑:

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException 
    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;
    HttpSession session = request.getSession(false);
    User user = (session != null) ? (User) session.getAttribute("user") : null;
    String loginURL = request.getContextPath() + "/faces/Login.xhtml"; 

    if (user == null && !request.getRequestURI().equals(loginURL))        
        response.sendRedirect(loginURL);
     else 
        chain.doFilter(request, response);
    

【讨论】:

谢谢BalusC,它成功了,你能帮我理解吗? “/faces/*”和“*.xhtml”有什么区别 这是应该调用 FacesServlet 的 URL 模式。如果是/faces/*,那么它只会在匹配/faces/* 的URL 上调用。如果是*.xhtml,那么它只会在匹配*.xhtml 的URL 上调用。使用*.xhtml 不会导致不必要的额外路径,您也不需要到处摆弄这个虚拟路径。我觉得有道理吗?

以上是关于从 servlet 过滤器重定向到 jsf 会返回未呈现为 html 的实际 jsf 代码的主要内容,如果未能解决你的问题,请参考以下文章

Servlet过滤器重定向,url没有改变

Servlet过滤器重定向:如何在chain.doFilter(request,resp)之后重定向;

在 servlet 过滤器中使用请求参数将 JSF ajax 请求重定向到 URL

从过滤器重定向到 JSP 时传递属性:会话与请求

服务器重定向和客户端重定向

通过过滤器设置 FacesMessage