天天看点

java实现单一登录,重复登录,用户登录后再次登录相同用户,会踢掉第一次登录用户(类似QQ登录)

java实现单一登录(类似QQ登录)

    • 一、业务需求
    • 二、具体实现
      • 实现思路
      • 具体代码

一、业务需求

账号已在web端登录后,再次登录相同账号将踢掉前一次的登录信息。

二、具体实现

实现思路

1.通过定义一个全局map变量sessionMap来保存用户登录成功时session对象,key为userId,value为HttpSession对象。

2.用户登录成功时将用户信息及session存入sessionMap(同一浏览器session相同)。

3.定义一个全局拦截器Interceptor,拿当前session对象与通过userId获取的HttpSession对象去对比,如果不一致则异地登录,此时给出提示并且跳转到登录页面。

4.(页面操作)当用户在第一次登录页面执行操作时,拦截器进行拦截,由于session不同拦截,而用户在第二次登录页面由于最新sessionMap的session存的就是这个,不会拦截。

5.over。

具体代码

  1. 登录控制器UsersController
@Controller
public class UsersController {
	@Autowired
	private UsersService usersServiceImpl;
	
	//key为用户id,value为用户登录时session(同一浏览器session相同)
	public static HashMap<String,HttpSession> sessionMap = new HashMap<>();
	
	@RequestMapping("/usersLogin")
	public String login(Users users,HttpSession session,HttpServletRequest req) {
		Users user = usersServiceImpl.selByUsers(users);
		if(user != null) {
			//登录成功
			session.setAttribute("user",user);
			// 添加本次登录用户的sessionMap,当前userId已有记录则覆盖
			String userId = String.valueOf(user.getId());
			sessionMap.put(userId, session);
			if(user.getRid() == UsersService.ADMIN_ID) {
				//后台首页
				return "redirect:toAdminIndex";
			}else if(user.getRid() == UsersService.USER_ID) {
				//前端首页
				return "redirect:toIndex";
			}
		}
		return "redirect:toLogin";
	}
}
           

2.springmvc配置拦截器

<!-- Interceptor拦截器 -->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <mvc:exclude-mapping path="/toLogin"/>
            <bean class="com.novel.interceptor.MainInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
           

3.拦截器实现类MainInterceptor

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.novel.controller.UsersController;
import com.novel.pojo.Users;

public class MainInterceptor implements HandlerInterceptor {

	/**
     * 	预处理回调方法,实现处理器的预处理(如检查登陆),第三个参数为响应的处理器,自定义Controller
     * 	返回值:true表示继续流程(如调用下一个拦截器或处理器);
     * false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;
     */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		//设置request,response字符集,否则输出的script会乱码
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		Users user = (Users) request.getSession().getAttribute("user");
		if(user!=null) {
			String userId = String.valueOf(user.getId());
			HttpSession httpSession = (HttpSession) UsersController.sessionMap.get(userId);
			//异地登录
			if(!httpSession.getId().equals(request.getSession().getId())){
				//跳转至登录页面
				response.getWriter().println(
						"<script type='text/javascript'>"
						+ "alert('您的账号已在异地登录,请重新登录!'); "
						+ "top.location.href='"
						+ request.getContextPath()+ "/toLogin"  + "';</script>");
				return false;
			}
		}else {
			//跳转至登录页面
			response.getWriter().println(
					"<script type='text/javascript'>"
					+ "alert('尚未登录或者登录超时,请重新登录!!'); "
					+ "top.location.href='"
					+ request.getContextPath()+ "/loginPage"  + "';</script>");
			return false;
		}
		
		return true;
	}
	 /**
     * 	后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)
     * 	对模型数据进行处理或对视图进行处理,modelAndView也可能为null。
     */
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub

	}
	/**
    *	整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,
    *	还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中
    */
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub

	}

}

           

4.正常注销账号时remove当前用户sessionMap

@RequestMapping("/toLogin")
	public String login(HttpServletRequest req) throws Exception {
		Users user = (Users) req.getSession().getAttribute("user");
		if(user!=null) {
			UsersController.sessionMap.remove(String.valueOf(user.getId()));
			req.getSession().removeAttribute("user");
		}
		return "login";
	}
@RequestMapping("/loginPage")
	public String loginPage(HttpServletRequest req) throws Exception {
		return "login";
	}