如何验证用户是否已登录和会话是否过期???

时间:2022-08-31 11:25:56
在一些网站中是如何检测用户是否已登录,或会话是否过期的,比如由于长时间未操作,导致会话过期了,但是你点击某一个链接是就弹出对话框提醒你会话已过期并跳转至登录页面;
以下是我用Struts2中的filter检测用户是否登录的代码:
一、SessionFilter.java

public class SessionFilter implements Filter {


public void destroy() {
System.out.println("This is Filter's Destroy!!!");
}

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//String currentURL = request.getRequestURI();  // 获得根目录对应的绝对路径
/**
 * 如 "/abc/test.jsp"  则  abc之前的 "/" 表示第0个,indexOf("/", 1)是得到字符串中第二次出现"/"
 */
//String targetURL = currentURL.substring(currentURL.indexOf("/", 1), currentURL.length());  // 截取到当前文件名用于比较
//System.out.println("currentURL = " + currentURL + " || targetURL = " + targetURL);
/*
HttpSession session = (HttpSession) request.getSession(false);  // 表示如果有session则使用当前session,没有也不创建
if(session == null){
response.sendRedirect("");  // 重定向到 500Error.jsp页面,并提示“由于长时间操作,请重新登录”
}
*/
/**
 * 判断系统管理后台登录用户会话是否过期
 * 如果过期,则重定向到登录界面,否则继续执行
 */
                   // USER_ID  是用户登录后保存的用户id
if(request.getSession().getAttribute("USER_ID") == null){ 
                           System.out.println("用户尚未登录 request.getSession().getAttribute('USER_ID') == null"); response.sendRedirect(request.getContextPath() +  "/login.jsp");
}
filterChain.doFilter(request, response);
}

public void init(FilterConfig arg0) throws ServletException {

System.out.println("This is Filter's Initialization!!!");
}

}


二、web.xml

<!-- Session isExpired Config -->
<filter>
<filter-name>SessionFilter</filter-name>
<filter-class>net.zontin.ynsignature.filter.SessionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


但是问题就出现了,当我访问首页 http://localhost:8080/项目名/index.jsp  时,因为首页的内容是通过ajax异步提交给action获得数据库中的值像是在页面上的,可是filter中有要检测是否登录,这样的话因为首页肯定没有登录,所以结果就是控制台一直不停的打印“用户尚未登录 request.getSession().getAttribute('USER_ID') == null”这个信息( 红色标注地方),就是不显示首页的内容,很是郁闷,请教各位高手如何解决这个问题……

13 个解决方案

#1


直接用servletRequest请求就可以了,不需要httpservletRequest

#2


给部分页面加个标志呗,如果是指定的标志,就不过滤了。

#3


引用楼主 dragonsky_w 的回复:
        if(request.getSession().getAttribute("USER_ID") == null){ 
                           System.out.println("用户尚未登录 request.getSession().getAttribute('USER_ID') == null");         response.sendRedirect(request.getContextPath() +  "/login.jsp");
        }

将首页忽略就行了
if (!request.getRequestURI.equals("/首页URL") && request.getSession().getAttribute("USER_ID") == null){
...

#4


同意楼上,将不需要过滤的页面忽略掉

#5


貌似用session 比较简单一点耶  呵呵  我菜鸟。。。

#6


你过滤并不是每一个地方都过滤吧,首页不过滤就好了

#7


引用 3 楼 magong 的回复:
引用楼主 dragonsky_w 的回复:
if(request.getSession().getAttribute("USER_ID") == null){
System.out.println("用户尚未登录 request.getSession().getAttribute('USER_ID') == null"); response.sendRedirect(request.getCo……


貌似我用以下代码,还是不行啊

if((request.getRequestURI().indexOf("/web/") < 0 || request.getRequestURI().indexOf("/web/index.jsp") < 0) && request.getSession().getAttribute("USER_ID") == null){
if(request.getSession().getAttribute("USER_ID") == null){ 
System.out.println("request.getSession().getAttribute('USER_ID') == null");
response.sendRedirect(request.getContextPath() +  "/web/index.jsp");
}
}


貌似还是执行了 System.out.println("request.getSession().getAttribute('USER_ID') == null");   这一句,为什么????

#8


Ajax提交的请求?
你把request.getRequestURI()打印出来看看。

#9


引用 8 楼 magong 的回复:
Ajax提交的请求?
你把request.getRequestURI()打印出来看看。


这个不是Ajax的请求,我的首页访问可以使 http://localhost:8080/项目名/web/   
或 http://localhost:8080/项目名/web/index.jsp 
我用request.getRequestURI()打印出来的结果是 /项目名/web/ 或  /项目名/web/index.jsp 

#10


额,一半情况下需要过滤的jsp文件写到一个单独的文件夹下面,然后flter就过滤指定的文件夹
比如admin需要过滤,配置文件改下就好,如果flter判断就稍微麻烦点,需要把需要过滤的jsp页面名称放到一个map或list中。。。然后循环判断过滤,类似于3楼那种

<url-pattern>/admin/*</url-pattern>

#11


酱油爱好者``````

#12


你可以用struts2的拦截器来做 ,自己写filter ,然后和写在配置文件里就可以了 ,很简单
给你提供一段代码

public class AuthorInterceptor extends AbstractInterceptor {

IAuthService authService;
public void setAuthService(IAuthService authService) {
this.authService = authService;
}
@SuppressWarnings("unchecked")
@Override
public String intercept(ActionInvocation invocation) throws Exception {
       String actionName =invocation.getInvocationContext().getName(); 
       ActionContext ctx = invocation.getInvocationContext(); 
       Map session = ctx.getSession(); 
       HttpServletRequest request = (HttpServletRequest)ctx.getContext().get(ServletActionContext.HTTP_REQUEST);
       
       
       if("login".equals(actionName) || "logout".equals(actionName) || "initSysData".equals(actionName)){
        return invocation.invoke(); 
       }else{
        Op op = (Op)session.get("currentUser");
        if(op==null){
        return  Action.LOGIN; 
        }
        
        return invocation.invoke(); 
    
       }
}

}

#13


引用 9 楼 dragonsky_w 的回复:
if((request.getRequestURI().indexOf("/web/") < 0 || request.getRequestURI().indexOf("/web/index.jsp") < 0) && request.getSession().getAttribute("USER_ID") == null){


这个不是Ajax的请求,我的首页访问可以使 http://localhost:8080/项目名/web/   
或 http://localhost:8080/项目名/web/index.jsp 
我用request.getRequestURI()打印出来的结果是 /项目名/web/ 或 /项目名/web/index.jsp  

不可能啊,对照9楼和7楼代码,没理由进if的啊。

#1


直接用servletRequest请求就可以了,不需要httpservletRequest

#2


给部分页面加个标志呗,如果是指定的标志,就不过滤了。

#3


引用楼主 dragonsky_w 的回复:
        if(request.getSession().getAttribute("USER_ID") == null){ 
                           System.out.println("用户尚未登录 request.getSession().getAttribute('USER_ID') == null");         response.sendRedirect(request.getContextPath() +  "/login.jsp");
        }

将首页忽略就行了
if (!request.getRequestURI.equals("/首页URL") && request.getSession().getAttribute("USER_ID") == null){
...

#4


同意楼上,将不需要过滤的页面忽略掉

#5


貌似用session 比较简单一点耶  呵呵  我菜鸟。。。

#6


你过滤并不是每一个地方都过滤吧,首页不过滤就好了

#7


引用 3 楼 magong 的回复:
引用楼主 dragonsky_w 的回复:
if(request.getSession().getAttribute("USER_ID") == null){
System.out.println("用户尚未登录 request.getSession().getAttribute('USER_ID') == null"); response.sendRedirect(request.getCo……


貌似我用以下代码,还是不行啊

if((request.getRequestURI().indexOf("/web/") < 0 || request.getRequestURI().indexOf("/web/index.jsp") < 0) && request.getSession().getAttribute("USER_ID") == null){
if(request.getSession().getAttribute("USER_ID") == null){ 
System.out.println("request.getSession().getAttribute('USER_ID') == null");
response.sendRedirect(request.getContextPath() +  "/web/index.jsp");
}
}


貌似还是执行了 System.out.println("request.getSession().getAttribute('USER_ID') == null");   这一句,为什么????

#8


Ajax提交的请求?
你把request.getRequestURI()打印出来看看。

#9


引用 8 楼 magong 的回复:
Ajax提交的请求?
你把request.getRequestURI()打印出来看看。


这个不是Ajax的请求,我的首页访问可以使 http://localhost:8080/项目名/web/   
或 http://localhost:8080/项目名/web/index.jsp 
我用request.getRequestURI()打印出来的结果是 /项目名/web/ 或  /项目名/web/index.jsp 

#10


额,一半情况下需要过滤的jsp文件写到一个单独的文件夹下面,然后flter就过滤指定的文件夹
比如admin需要过滤,配置文件改下就好,如果flter判断就稍微麻烦点,需要把需要过滤的jsp页面名称放到一个map或list中。。。然后循环判断过滤,类似于3楼那种

<url-pattern>/admin/*</url-pattern>

#11


酱油爱好者``````

#12


你可以用struts2的拦截器来做 ,自己写filter ,然后和写在配置文件里就可以了 ,很简单
给你提供一段代码

public class AuthorInterceptor extends AbstractInterceptor {

IAuthService authService;
public void setAuthService(IAuthService authService) {
this.authService = authService;
}
@SuppressWarnings("unchecked")
@Override
public String intercept(ActionInvocation invocation) throws Exception {
       String actionName =invocation.getInvocationContext().getName(); 
       ActionContext ctx = invocation.getInvocationContext(); 
       Map session = ctx.getSession(); 
       HttpServletRequest request = (HttpServletRequest)ctx.getContext().get(ServletActionContext.HTTP_REQUEST);
       
       
       if("login".equals(actionName) || "logout".equals(actionName) || "initSysData".equals(actionName)){
        return invocation.invoke(); 
       }else{
        Op op = (Op)session.get("currentUser");
        if(op==null){
        return  Action.LOGIN; 
        }
        
        return invocation.invoke(); 
    
       }
}

}

#13


引用 9 楼 dragonsky_w 的回复:
if((request.getRequestURI().indexOf("/web/") < 0 || request.getRequestURI().indexOf("/web/index.jsp") < 0) && request.getSession().getAttribute("USER_ID") == null){


这个不是Ajax的请求,我的首页访问可以使 http://localhost:8080/项目名/web/   
或 http://localhost:8080/项目名/web/index.jsp 
我用request.getRequestURI()打印出来的结果是 /项目名/web/ 或 /项目名/web/index.jsp  

不可能啊,对照9楼和7楼代码,没理由进if的啊。