栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如果JSF页面受j_security_check保护,则不会在ajax请求上引发ViewExpiredException

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如果JSF页面受j_security_check保护,则不会在ajax请求上引发ViewExpiredException

我能够重现您的问题。这里发生的是容器

RequestDispatcher#forward()
按照安全性约束中的指定调用登录页面。但是,如果登录页面本身也就是JSF页面,则
FacesServlet
还将在转发的请求上调用。由于请求是转发的,因此只会在转发的资源(登录页面)上创建一个新视图。但是,由于这是一个ajax请求,并且没有任何
render
信息(整个POST请求在安全检查转发过程中基本上被丢弃),因此仅返回视图状态。

请注意,如果登录页面不是JSF页面(例如JSP或纯HTML),那么ajax请求将返回该页面的整个HTML输出作为ajax响应,这是JSF
ajax无法解析的,并被解释为“空”响应。

不幸的是,它是“按设计的”方式工作的。我怀疑JSF规范中对ajax请求的安全性约束检查有一些疏忽。毕竟,原因是可以理解的,而且很容易解决。只是,您实际上并不希望在此处显示错误页面,而是仅显示整个登录页面,这与非ajax请求期间的情况完全相同。您只需要检查当前请求是否为ajax请求并将其转发到登录页面,则需要发送特殊的“重定向”
ajax响应,以便更改整个视图。

您可以通过以下方法实现此目的

PhaseListener

    public class AjaxLoginListener implements PhaseListener {        @Override        public PhaseId getPhaseId() { return PhaseId.RESTORE_VIEW;        }        @Override        public void beforePhase(PhaseEvent event) { // NOOP.        }        @Override        public void afterPhase(PhaseEvent event) { FacesContext context = event.getFacesContext(); HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest(); String originalURL = (String) request.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI); String loginURL = request.getContextPath() + "/login.xhtml"; if (context.getPartialViewContext().isAjaxRequest()     && originalURL != null     && loginURL.equals(request.getRequestURI())) {     try {         context.getExternalContext().invalidateSession();         context.getExternalContext().redirect(originalURL);     } catch (IOException e) {         throw new FacesException(e);     } }        }    }

更新 此解决方案是因为OmniFaces
1.2
已内置到

OmniPartialViewContext
。因此,如果您碰巧已经使用过OmniFaces,则可以完全透明地解决此问题,并且不需要
PhaseListener
为此自定义。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/380376.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号