从 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过滤器重定向:如何在chain.doFilter(request,resp)之后重定向;