首先这里有两个登录页面,一个登录页面让管理员和普通用户登录,一个页面让超级管理员登录。咱们这里先不要研究登录界面安排的是否合理,咱就看看对于两个页面,多个用户登录,过滤器到底该怎么设置。
之前对于设置一个登录页面的过滤器的时候(链接在这),会在用户访问其他页面之前,验证Session里面的用户登录信息是否存在,存在就允许访问了,不存在就返回到了登录界面。但因为我是像下面这样设置的,所以未登录返回到登录界面就不好处理了。
只有一个登录页面的时候,在action类中,我根据用户在登陆页面提交的个人信息为查询条件,到数据库查询,然后存储在session中,三个用户都使用的是同一个名字"user",如下
HttpServletRequest request = ServletActionContext.getRequest();
HttpSession session = (HttpSession) request.getSession();
//此处省略部分代码
.......
session.setAttribute("user", admin);
过滤器里面主要通过判断这句话,来决定让不让用户访问登录以外的页面:
request1.getSession().getAttribute("user") ==null
这样的话,会存在两个问题:
1、对于一个登录页面,是能够让用户未登录就访问其他页面时,返回到登录界面的,但是对于多个登录界面的话,就无法判断返回到哪一个界面。
2、用同一个键名“user”,会有bug存在。比如管理员登录成功了,你会发现他不仅能访问管理员主界面,也能访问普通用户界面和管理员界面,因为request1.getSession().getAttribute("user") !=null
如果只想解决第一个问题,
那么,可以再添加一个登录错误提示页面,这样只要request1.getSession().getAttribute("user") ==null
,就让其跳转到错误提示页面即可,则过滤器像下面这样写:
public class MyFilter implements Filter {
/**
* Default constructor.
*/
public MyFilter() {
// TODO Auto-generated constructor stub
}
/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("========我是自定义过滤器=========");
HttpServletRequest request1 = (HttpServletRequest) request;
HttpServletResponse response1 = (HttpServletResponse) response;
// 如果是Ajax请求,则值为XMLHttpEequest
String type = request1.getHeader("X-Requested-With") == null ? "" : request1.getHeader("X-Requestesd-With");
String url = request1.getServletPath();
/* String contextPath =request1.getContextPath(); */
if (url.equals(""))
url += "/";
// 对两个登录页面设置的过滤器
if ((url.startsWith("/") && !url.startsWith("/jsp/login")))
{
if(!url.startsWith("/jsp/superlogin"))
{
if ((request1.getSession().getAttribute("user") ==null) ) {
// 为null:用户未登录,让其访问error页面
if ("XMLHttpRequest".equals(type)) { // 处理Ajax请求,设置响应头信息
response1.setHeader("REDIRECT", "REDIRECT");
response1.setHeader("CONTEXTPATH", request1.getContextPath() + "/jsp/loginerror.jsp"); //需要跳转的页面
System.out.println("==========user为空 访问loginerror.jsp====1=========");
}else {
response1.sendRedirect(request1.getContextPath() + "/jsp/loginerror.jsp");
System.out.println("==========user为空访问 loginerror.jsp====2=========");
}
////////////////////////////////////////////////
} else{//admin和superadmin有一个不为空,访问其他页面就放行
chain.doFilter(request, response);
System.out.println("==========user不为空===chain======");
}
//////////////////////////////////////
}else{ //访问了superlogin.jsp 放行
chain.doFilter(request, response);
System.out.println("==========superlogin.jsp=====chain====");
}
/////////////////////////////////////////////////////
}else{ //访问了login.jsp 放行
if(url.startsWith("/jsp/loginerror")) //访问loginerror.jsp 放行
{
System.out.println("==========loginerror.jsp=====chain====");
chain.doFilter(request, response);
}else{
System.out.println("==========login.jsp=====chain====");
chain.doFilter(request, response);
}
}
}
对于同时解决1、2问题
,我没写,但是好改。首先用Session存储三种用户的登录信息时,记得使用不同键名,不要都使用"user"。 然后过滤器过滤器分别判断
request1.getSession().getAttribute("admin") ==null
request1.getSession().getAttribute("superadmin") ==null
request1.getSession().getAttribute("client") ==null
是否为真?为真时,访问其他页面时,就跳转到对应的登录页面,否则就显示访问的页面。这样不仅解决了用户访问其他用户主界面的同时,也成功解决了该返回到哪个登录页面的问题,感兴趣的可以自己试一下。
如果我这里有写错的地方,还望告诉我一下哇!