由于页面的Ajax的定时请求服务器,导致了当前用户session永远不会超时。所以我决定用Filter过滤器加Timer的方法来解决这个问题,我在代码里用户每一次访问会新建的Timer,清除上一个Timer,但是发现我怎样做都不会清除上一个Timer,他到时间还是会执行!请问这个有什么错误,应该怎么解决啊?或者可以用别的什么方案来解决不超时的问题!非常感谢,代码如下!import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;public class SessionTimeOutFilter implements Filter {
private int num = -1;
private String filterUrl;
private String sessionKey;
private static Map<String,Timer> map = new HashMap<String,Timer>(); public void init(FilterConfig filterConfig) throws ServletException {
sessionKey = filterConfig.getInitParameter("SessionKey");
filterUrl = filterConfig.getInitParameter("filterUrl");
}
public void destroy() {} public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
if(num<0){
num = request.getSession().getMaxInactiveInterval();
}
String url = request.getServletPath();
if(url!=null && !"".equals(url) && !filterUrl.equals(url)){
HttpSession session = request.getSession();
Timer timer = map.get(session.getId());
if(timer!=null){
map.remove(session.getId());
timer.cancel();
timer = null;
}
timer = new Timer();
timer.schedule(new SessionTimeOut(session,sessionKey), num * 1000);
map.put(session.getId(), timer);
}
chain.doFilter(req, resp);
} class SessionTimeOut extends TimerTask {
private HttpSession session;
private String sessionKey;
public SessionTimeOut(HttpSession session, String sessionKey){
this.session = session;
this.sessionKey = sessionKey;
}
public void run() {
if(session!=null){
session.removeAttribute(sessionKey);
//this.session.invalidate();
}
}
}
}
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;public class SessionTimeOutFilter implements Filter {
private int num = -1;
private String filterUrl;
private String sessionKey;
private static Map<String,Timer> map = new HashMap<String,Timer>(); public void init(FilterConfig filterConfig) throws ServletException {
sessionKey = filterConfig.getInitParameter("SessionKey");
filterUrl = filterConfig.getInitParameter("filterUrl");
}
public void destroy() {} public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
if(num<0){
num = request.getSession().getMaxInactiveInterval();
}
String url = request.getServletPath();
if(url!=null && !"".equals(url) && !filterUrl.equals(url)){
HttpSession session = request.getSession();
Timer timer = map.get(session.getId());
if(timer!=null){
map.remove(session.getId());
timer.cancel();
timer = null;
}
timer = new Timer();
timer.schedule(new SessionTimeOut(session,sessionKey), num * 1000);
map.put(session.getId(), timer);
}
chain.doFilter(req, resp);
} class SessionTimeOut extends TimerTask {
private HttpSession session;
private String sessionKey;
public SessionTimeOut(HttpSession session, String sessionKey){
this.session = session;
this.sessionKey = sessionKey;
}
public void run() {
if(session!=null){
session.removeAttribute(sessionKey);
//this.session.invalidate();
}
}
}
}
你可以先不要调用request.getSession(),防止当会话超时后再次访问时会创建一个空白的Session
还有,你的这句:if(url!=null && !"".equals(url) && !filterUrl.equals(url))里的语句确实被执行了吗?
问题是我的Ajax请求是请求的后台,是要去读数据库的,相当于去监视数据库是否有新数据。那上面的方法还有用么?
何不直接把Timer放在session里?
另外:过滤器是可以设定过滤哪些url的。你可以通过这个来指定而不是通过过滤器内部来分析,因为这是可以灵活配置的。
你以前有什么问题?
我放入session中,然后取出来然后清除Timer,重新放入一个新的Timer,问题就是前一个Timer根本不会清除,到时间他还是会执行!!!
在page标签内设置session="false"禁用当前页的session,要是我这个页面是个总的框架Fream怎么办?不会影响子框架?
而且我看了看相关文档session="false"只是在本页面里session没有用,其实请求和超时的计算都还是在啊,根本没用,而且会导致其它问题,我要是想取seesion中的元素怎么办?
public void doFilter(HttpServletRequest request,
HttpServletResponse response, FilterChain chain) throws Exception {
if(request.getRequestURI().equals(url)) {
HttpSession session = request.getSession(false);
if(session != null) {
Date date = (Date) session.getAttribute("_LAST_ACCESS_TIME");
if(System.currentTimeMillis() - date.getTime() > 10 * 60 * 1000) {
session.invalidate();
} else
chain.doFilter(request, response);
}
} else {
HttpSession session = request.getSession();
session.setAttribute("_LAST_ACCESS_TIME", new Date());
chain.doFilter(request, response);
}
}
Timer么……嗯,过多的Timer恐怕更不好。这是个话题,值得讨论。
是不是用一个专门的监控线程会好些?或者用一个全局的Timer,结合10楼的?