忽略 ViewExpiredException 是错误的?
It is wrong to ignore ViewExpiredException?
一周前,我研究了 ViewExpiredException,并阅读了一些相关内容。
- viewExpiredException JSF
- How to control web page caching, across all browsers?
- Session timeout and ViewExpiredException handling on JSF/PrimeFaces ajax request
我的问题,这是某些情况下,我想忽略的ViewExpiredException
。这些是不需要 "session" 的情况,而我的 Beans 是 @RequestScoped
。例如,页面 login.xhtml
、register.xhtml
和 passwordRecovery.xhtml
.
在这些情况下,向用户显示您的会话已过期的错误是非常奇怪的。所以如果你打开登录页面静止不动,当他通知你数据,点击登录时,就会跳转到一个错误页面。我会忽略它并让用户透明。
所以,到目前为止,我的解决方案是创建一个 ExceptionHandler
来忽略这些异常:
@Override
public void handle() throws FacesException {
for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) {
ExceptionQueuedEvent event = i.next();
ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
Throwable t = context.getException();
// just remove the exception from queue
if (t instanceof ViewExpiredException) {
i.remove();
}
}
getWrapped().handle();
}
然后,我创建了一个过滤器来检查用户是否已登录,如果没有则重定向到登录页面(此过滤器仅适用于需要身份验证的页面):
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
if (!loginManagedBean.isLogged()) {
String pathLogin = request.getContextPath() + "/" + LOGIN_VIEW;
if (isAJAXRequest(request)) {
response.setContentType("text/xml");
response.getWriter()
.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
.printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>", pathLogin);
return;
}
pathLogin += "?source=" + request.getServletPath();
response.sendRedirect(pathLogin);
return;
}
chain.doFilter(request, response);
}
所以当session过期时,不影响登录和注册页面的用户体验。在我希望会话的页面上,由过滤器处理。
那会是一个好的解决方案吗?在 ExceptionHandler
中是否存在可忽略 ViewExpiredException
的安全风险?
在这种特定情况下,忽略它们在技术上并不坏,但它表明设计不好。就好像您在工作中使用了错误的工具。 IE。这些视图实际上应该永远不会过期。
只需专门使那些视图无状态即可。
<f:view transient="true">
...
</f:view>
这可以放在页面的任何位置,甚至可以重复,但大多数自我记录是将其作为页面、组合或定义的顶级标签。
另请参阅:
- What is the usefulness of statelessness in JSF?
一周前,我研究了 ViewExpiredException,并阅读了一些相关内容。
- viewExpiredException JSF
- How to control web page caching, across all browsers?
- Session timeout and ViewExpiredException handling on JSF/PrimeFaces ajax request
我的问题,这是某些情况下,我想忽略的ViewExpiredException
。这些是不需要 "session" 的情况,而我的 Beans 是 @RequestScoped
。例如,页面 login.xhtml
、register.xhtml
和 passwordRecovery.xhtml
.
在这些情况下,向用户显示您的会话已过期的错误是非常奇怪的。所以如果你打开登录页面静止不动,当他通知你数据,点击登录时,就会跳转到一个错误页面。我会忽略它并让用户透明。
所以,到目前为止,我的解决方案是创建一个 ExceptionHandler
来忽略这些异常:
@Override
public void handle() throws FacesException {
for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) {
ExceptionQueuedEvent event = i.next();
ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
Throwable t = context.getException();
// just remove the exception from queue
if (t instanceof ViewExpiredException) {
i.remove();
}
}
getWrapped().handle();
}
然后,我创建了一个过滤器来检查用户是否已登录,如果没有则重定向到登录页面(此过滤器仅适用于需要身份验证的页面):
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
if (!loginManagedBean.isLogged()) {
String pathLogin = request.getContextPath() + "/" + LOGIN_VIEW;
if (isAJAXRequest(request)) {
response.setContentType("text/xml");
response.getWriter()
.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
.printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>", pathLogin);
return;
}
pathLogin += "?source=" + request.getServletPath();
response.sendRedirect(pathLogin);
return;
}
chain.doFilter(request, response);
}
所以当session过期时,不影响登录和注册页面的用户体验。在我希望会话的页面上,由过滤器处理。
那会是一个好的解决方案吗?在 ExceptionHandler
中是否存在可忽略 ViewExpiredException
的安全风险?
在这种特定情况下,忽略它们在技术上并不坏,但它表明设计不好。就好像您在工作中使用了错误的工具。 IE。这些视图实际上应该永远不会过期。
只需专门使那些视图无状态即可。
<f:view transient="true">
...
</f:view>
这可以放在页面的任何位置,甚至可以重复,但大多数自我记录是将其作为页面、组合或定义的顶级标签。
另请参阅:
- What is the usefulness of statelessness in JSF?