我有一个JSF Phase Listerner,用于检查用户是否已登录,如果没有,则将其重定向到登录页面。这适用于非ajax请求。但是,如果用户在一个页面上,在我的情况下,一个有一个primefaces数据表,并点击一个调用ajax请求的按钮 - 但他们的会话超时 - 代码被执行,发出重定向(使用ExternalContext#redirect
),但用户未导航到登录页面。
知道为什么这不起作用吗?
这是我的阶段监听器:
private static final String IS_LOGGED_IN_INDICATOR = "loggedIn";
private static final String LOGIN_PAGE = "/login.jsp";
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
public void beforePhase(PhaseEvent event) {
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
HttpSession session = (HttpSession)ec.getSession(false);
if (session==null || session.getAttribute(IS_LOGGED_IN_INDICATOR) == null) {
try {
ec.redirect(LOGIN_PAGE);
}
catch(IOException e) {
// log exception...
}
}
}
public void afterPhase(PhaseEvent event) {
// no-op
}
}
答案 0 :(得分:3)
失败是因为ajax上下文试图从视图根获取渲染工具包,而根本没有视图根。它尚未在那时恢复。这导致NullPointerException
中的PartialViewContext#createPartialResponseWriter()
。反过来,这个异常不会被抛出,而是放在一个应该由自定义ExceptionHandler
处理的ajax异常队列中。你显然没有任何一个。如果您创建/使用FullAjaxExceptionHandler
之类的此类异常,则会显示此异常(有关详细信息,另请参阅this blog)。
要解决特定问题,请改为使用afterPhase()
中的作业。然后完全恢复视图根,并且ajax上下文可以从中获取渲染工具包,以便编写专门的XML响应,该响应指示JavaScript中的JSF ajax引擎更改窗口位置。如果没有ajax,则不需要渲染工具包,因为重定向基本上只是设置响应头。
特定NullPointerException
是否是Mojarra中的错误是一个不同的问题,可以更好地在他们自己的问题跟踪器上发布问题报告的风格。
答案 1 :(得分:-1)
这是因为你必须在XML中为Ajax请求发送一个特殊的响应才能进行重定向(检查this answer),我已经在这样的过滤器中实现了这个..
// Check if it's an Ajax Request
if ("partial/ajax".equals(((HttpServletRequest) request).getHeader("Faces-Request"))) {
//redirect
response.setContentType("text/xml");
response.getWriter()
.append("<?xml version= \"1.0\" encoding=\"UTF-8\"?>")
.printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>",url);
你应该将它移植到你的Phase Listener。