我找到了问题的根本原因。
根本原因:
问题不在于 spring 3.0.5 版本或某些配置。这一切都归功于我的一个 js 文件中的一小段代码:
/* session timeout handling */
Ext.Ajax.on("requestcomplete", function(conn, response, options){
//We can do nicer things here, like showing a login window and let
//the user login on the same screen. But now we simply redirects the
//user to the login page.
if(response.responseText.indexOf("<html>") > 0){
window.location = mFino.BASE_URL + "login.htm";
}
});
这里要做的是:由于我们的网站完全是使用 extjs 构建的,我们确实发送了 ajax 请求,所以如果我们发送一个 ajax 请求,让我们说“fix.htm”(一旦用户一次登录多个系统),序列过滤器被调用,当 ConcurrentSessionFilter 被调用时,重定向发生在“concurrent.jsp”并且过滤被终止(当然,正如我所说的,当一次发送多个请求时,即使在并发过滤器中发生重定向并且过滤器被终止,另一个请求将通过定义的过滤器,而不管第一个请求是否被重定向 - 然后在异常过滤器中引发 AccessDeniedException 并重定向到 login.htm 并行发生 - 但这不是根本原因,因为即使只有 1 ajax 请求已发送)所以最后是并发的。jsp 内容作为对 ajax 请求的响应发送。
内容(即 response.responseText 中的
Ext.Ajax.on("requestcomplete", function(conn, response, options))
将是一个类似于...的html页面
"<html>
<head>
<title>Adminapplication- concurrency issue page</title>......."
由于满足条件,用户将根据代码重定向到登录页面:
if(response.responseText.indexOf("<html>") > 0){
window.location = mFino.BASE_URL + "login.htm";
}
保持此条件的目的是:通常,ajax 请求的响应将是 JSON 或 XML 类型的示例,例如:
{success:true, message:'User name is xxx'}
所以如果有的话,如果他们得到除了这种类型的响应(比如 html 响应),可以说是由于会话超时,他们只是重定向到login.htm。
这是影响我重定向到“ concurrent.htm ”的根本原因。
我为此想出的解决方案是:
将concurrenyHandler中的逻辑更改为发送 json 响应,而不是重定向到并发 jsp,这将生成 html 响应 ...如下:
前:
@RequestMapping("/concurrent.htm")
public View concurrenyHandler(HttpServletRequest request, HttpServletResponse response){
return new ModelAndView("concurrent");
}
后:
@RequestMapping("/concurrent.htm")
public View concurrenyHandler(HttpServletRequest request, HttpServletResponse response){
HashMap<String,Object> map = new HashMap<String, Object>();
map.put("success", true);
map.put("Error", MessageText._("Session Expired"));
return new JSONView(map); //JSONView is our custom class which implements org.springframework.web.servlet.View and renders json object as string just like ..."out.write(this.jsonObject.toString());"
}
在 js 文件中,将“on requestcomplete ”功能更改如下,
/* session timeout handling */
Ext.Ajax.on("requestcomplete", function(conn, response, options){
//We can do nicer things here, like showing a login window and let
//the user login on the same screen. But now we simply redirects the
//user to the login page.
/*if(response.responseText.indexOf("<html>") > 0){
window.location = mFino.BASE_URL + "login.htm";
}*/
if(response.responseText.indexOf("Session Expired") > 0){
window.location = mFino.BASE_URL + "login.htm?sessionExpired=true";
}
});
在 login.jsp 中,我将检查 sessionExpired=true 条件并使用以下消息发出警报,
if('<%=request.getParameter("sessionExpired")%>'=='true'){
alert("The session is expired due to timeout or because the same user logged in on another system");
}
更改弹簧设置如下:
.......<custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
<custom-filter ref="authenticationProcessingFilter" before="FORM_LOGIN_FILTER" />
<custom-filter ref="customSessionManagementFilter" after="SESSION_MANAGEMENT_FILTER" />
<session-management session-authentication-strategy-ref="sas" invalid-session-url="/concurrent.htm"/>
</http>
<beans:bean id="authenticationProcessingFilter" class="com.mfino.uicore.security.AuthProcessingFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="sessionAuthenticationStrategy" ref="sas" />
</beans:bean>
<beans:bean id="customSessionManagementFilter" class="com.mfino.uicore.security.CustomSessionManagementFilter">
</beans:bean>
<beans:bean id="concurrencyFilter"
class="org.springframework.security.web.session.ConcurrentSessionFilter" >
<beans:property name="sessionRegistry" ref="sessionRegistry" />
<beans:property name="expiredUrl" value="/concurrent.htm" />
</beans:bean>..........
现在,当根据需要发生并发异常时,我可以在登录页面中显示带有消息的警报[以前我担心的主要问题是我无法发送像'sessionExpired = true'这样的请求参数来检查登录页面中的条件并发出警报,因为我不断地被重定向到 login.htm(没有任何此类请求参数),而不管 Spring 处理程序完成的重定向]。
感谢@LukeTaylor 指导我!!!!