我发现本文对非ajax请求很有用。如何在JSF2中处理会话过期和ViewExpiredException?但当我使用AJAX调用提交时,我无法利用这一点。
假设在primefaces对话框中,我使用AJAX发出post请求,而会话已经超时。我看到我的页面卡住了。
如何修复这种情况,以便当我使用AJAX发布时,我可以将他重定向到我的视图过期页面,然后将他转发到类似于上面链接中的解决方案的登录页面?
JSF2/Primefaces/Glassfish
我在JBoss 7的生产模式下使用Mojarra 2.1.7。会话到期后,AJAX调用返回错误XML文档。您可以使用常见的f:ajax错误处理程序轻松捕获此错误。
<script type="text/javascript">
function showError(data) {
alert("An error happened");
console.log(data);
}
</script>
<h:commandLink action="...">
<f:ajax execute="..." render="..." onerror="showError"/>
</h:commandLink>
@BalusC的答案和这篇文章的合并,我解决了我的问题!
我的ExceptionHandlerWrapper:
public class CustomExceptionHandler extends ExceptionHandlerWrapper {
private ExceptionHandler wrapped;
CustomExceptionHandler(ExceptionHandler exception) {
this.wrapped = exception;
}
@Override
public ExceptionHandler getWrapped() {
return wrapped;
}
@Override
public void handle() throws FacesException {
final Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator();
while (i.hasNext()) {
ExceptionQueuedEvent event = i.next();
ExceptionQueuedEventContext context
= (ExceptionQueuedEventContext) event.getSource();
// get the exception from context
Throwable t = context.getException();
final FacesContext fc = FacesContext.getCurrentInstance();
final Map<String, Object> requestMap = fc.getExternalContext().getRequestMap();
final NavigationHandler nav = fc.getApplication().getNavigationHandler();
//here you do what ever you want with exception
try {
//log error ?
//log.log(Level.SEVERE, "Critical Exception!", t);
if (t instanceof ViewExpiredException) {
requestMap.put("javax.servlet.error.message", "Session expired, try again!");
String errorPageLocation = "/erro.xhtml";
fc.setViewRoot(fc.getApplication().getViewHandler().createView(fc, errorPageLocation));
fc.getPartialViewContext().setRenderAll(true);
fc.renderResponse();
} else {
//redirect error page
requestMap.put("javax.servlet.error.message", t.getMessage());
nav.handleNavigation(fc, null, "/erro.xhtml");
}
fc.renderResponse();
// remove the comment below if you want to report the error in a jsf error message
//JsfUtil.addErrorMessage(t.getMessage());
} finally {
//remove it from queue
i.remove();
}
}
//parent hanle
getWrapped().handle();
}
}
我的异常处理程序工厂:
public class CustomExceptionHandlerFactory extends ExceptionHandlerFactory {
private ExceptionHandlerFactory parent;
// this injection handles jsf
public CustomExceptionHandlerFactory(ExceptionHandlerFactory parent) {
this.parent = parent;
}
@Override
public ExceptionHandler getExceptionHandler() {
ExceptionHandler handler = new CustomExceptionHandler(parent.getExceptionHandler());
return handler;
}
}
我的 faces-config.xml
<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.2"
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-facesconfig_2_2.xsd">
<factory>
<exception-handler-factory>
your.package.here.CustomExceptionHandlerFactory
</exception-handler-factory>
</factory>
</faces-config>
默认情况下,ajax请求期间抛出的异常在客户端完全没有反馈。只有在运行Mojarra时,项目阶段设置为<code>Development</code>并使用<code>
您需要实现一个自定义的< code>ExceptionHandler,当队列中有< code > viewexpire exception 时,它基本上完成以下工作:
String errorPageLocation = "/WEB-INF/errorpages/expired.xhtml";
context.setViewRoot(context.getApplication().getViewHandler().createView(context, errorPageLocation));
context.getPartialViewContext().setRenderAll(true);
context.renderResponse();
或者,您可以使用JSF实用程序库OmniFaces。它有一个< code > FullAjaxExceptionHandler 就是为了这个目的(源代码在这里,showcase演示在这里)。
问题内容: 但是当我使用AJAX调用提交时无法使用此功能 假设在一个primefaces对话框中,我正在使用AJAX发出发布请求,并且会话已经超时。我看到页面卡住了。 如何解决这种情况,以便在我使用AJAX发布时,可以将他重定向到我的视图过期页面,然后将他转发到登录页面,类似于上面的链接中的解决方案? JSF2 / Primefaces /玻璃鱼 问题答案: 默认情况下,ajax请求期间引发的异常
是否有可能“拦截”会话超时? 我尝试了,但据我所知,当调用HttpSessionListener.session毁灭()'方法时,会话已经被摧毁。(所以我没有机会确定用户,拥有超时的会话) 另一个选项是PhaseListener,在restoreView阶段检查会话是否是“新的”。 但是,我需要在会话超时的“第二天”执行一些操作-不在以后的刷新中执行,也不在以后的登录中执行。 (背景:需要删除某些
我在解决如何正确处理JSF中会话的自动销毁方面遇到了困难。当然,此时,容器会使会话失效,从而也会在会话范围的bean上调用@PreDestroy方法。 在某些会话范围bean的预销毁中,我们正在注销一些侦听器,如下所示: 然而,getWS()方法实际上试图获取对另一个会话范围bean的引用,但失败了,如返回null。Ryan Lubke认为,后者似乎是正常的JSF行为: 我们遵守这里的规范。我不确
问题内容: 这似乎是一个非常普遍的问题。但是我找不到任何可行的解决方案。我们正在使用Richafaces 4,Myfaces 2.0.5和Spring security3.0.X。 在ajax / non ajax请求的会话时间上,应该将用户重定向到登录页面。登录回去后,应该向他显示先前执行的ajax / non ajax操作。 非ajax请求不会遇到任何问题。但是对于ajax请求,不会将用户重定
在 HTTP 协议中,当客户端不再处于活动状态时没有显示的终止信号。这意味着当客户端不再处于活跃状态时可以使用的唯一机制是超时时间。 Servlet 容器定义了默认的会话超时时间,且可以通过 HttpSession 接口的 getMaxInactiveInterval 方法获取。开发人员可以使用HttpSession 接口的 setMaxInactiveInterval 方法改变超时时间。这些方法
问题内容: 有什么方法可以使用Angularjs管理用户会话吗? 会话超时-系统空闲时。 在会话即将到期时发出警报,并带有恢复会话的选项。 如果会话已过期,则在尝试发出请求时重定向(或其他任何操作)。 拦截器可以解决这个问题吗?你能举个例子吗? 提前致谢。 问题答案: 尝试ng-idle。它是一个简单的组件,您可以在其中设置超时和警告时间,直到达到超时。然后,您可以查询服务器上的用户注销或类似内容
问题内容: 我正在使用请求模块(Python 2.5的版本0.10.0)。我已经弄清楚了如何将数据提交到网站上的登录表单并检索会话密钥,但是我看不到在后续请求中使用此会话密钥的明显方法。有人可以在下面的代码中填写省略号还是建议其他方法? 问题答案: 您可以使用以下方法轻松创建持久会话: 之后,请继续执行您的请求: 有关会话的更多信息,请访问:https : //requests.kennethre
问题内容: 无论我们是否检查会话变量,会话超时都会在每个请求上重置吗?还是我们应该使用至少一个会话变量? Ajax请求是否导致重置会话超时?像,… 谢谢 编辑1) 会导致重置会话超时吗? 问题答案: 是的,它确实。是否实际使用都没关系。 但是,如果 仅 使用ajax调用,则可能会遇到一些问题。 (虽然我还没有遇到过它自己,在这里的解释)