如何使用java实现简单扫码登录功能
这篇文章主要介绍如何使用java实现简单扫码登录功能,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
创新互联主营向阳网站建设的网络公司,主营网站建设方案,app软件开发,向阳h5重庆小程序开发公司搭建,向阳网站营销推广欢迎向阳等地区企业咨询
java实现简单扫码登录功能
模仿微信pc网页版扫码登录
使用js代码生成qrcode二维码减轻服务器压力
js循环请求服务端,判断是否qrcode被扫
二维码超时失效功能
二维码被扫成功登录,服务端产生sessionId,传到页面使用js保存cookie
多线程
生成qrcode相关js jquery.qrcode.js
代码
页面div
请使用手机扫码
主要js
//生成二维码 !function(){ var uuid = $("#uuid").val(); var content; content = "..........do?uuid="+uuid; //console.dir(content); $('.pc_qr_code').qrcode({ render:"canvas", width:200, height:200, correctLevel:0, text:content, background:"#ffffff", foreground:"black", src:"/logo.png" }); setCookie("sid", 123, -1*60*60*1000); keepPool();//自动循环调用 }(); function keepPool(){ var uuid = $("#uuid").val(); $.get(ctx+"/web/login/pool.do",{uuid:uuid,},function(msg){//如果放入一个不存在的网址怎么办? //console.log(msg); if(msg.successFlag == '1'){ $("#result").html("扫码成功"); setCookie(msg.data.cname, msg.data.cvalue, 3*60*60*1000); //alert("将跳转..."); window.location.href = ctx +"/webstage/login/success.do"; }else if(msg.successFlag == '0'){ $("#result").html("该二维码已经失效,请重新获取"); }else{ keepPool(); } }); } //设置cookie function setCookie(cname, cvalue, expireTime) { var d = new Date(); d.setTime(d.getTime() + expireTime);//设置过期时间 var expires = "expires="+d.toUTCString(); var path = "path=/" document.cookie = cname + "=" + cvalue + "; " + expires + "; " + path; }
java代码
//二维码首页 public String index() { try { uuid = UUID.randomUUID().toString(); super.getRequest().setAttribute("uuid", uuid); ScanPool pool = new ScanPool(); pool.setCreateTime(System.currentTimeMillis()); Mapmap = new HashMap (1); map.put(uuid, pool); PoolCache.cacheMap.put(uuid, pool); pool = null; } catch (Exception e) { Log4jUtil.CommonLog.error("pc生成二维码登录", e); } return "index"; } //判断二维码是否被扫描 public void pool() { DataResultInfo result = null; System.out.println("检测[ " + uuid + " ]是否登录"); ScanPool pool = null; if(MapUtils.isNotEmpty(PoolCache.cacheMap)) pool = PoolCache.cacheMap.get(uuid); try { if (pool == null) { // 扫码超时,进线程休眠 result = DataResultInfo.getInstance().failure(); result.setSuccessFlag(CommonConstant.Zero); result.setExtension(CommonConstant.Zero, "该二维码已经失效,请重新获取"); Thread.sleep(10 * 1000L); } else { // 使用计时器,固定时间后不再等待扫描结果--防止页面访问超时 new Thread(new ScanCounter(uuid, pool)).start(); boolean scanFlag = pool.getScanStatus(); //这里得到的ScanPool(时间靠前)和用户使用手机扫码后得到的不是一个,用户扫码后又重新更新了ScanPool对象,并重新放入了redis中,,所以这里要等待上面的计时器走完,才能获得最新的ScanPool if (scanFlag) { result = DataResultInfo.getSuccess(); // 根据uuid从redis中获取pool对象,得到对应的sessionId,返给页面,通过js存cookie中 JSONObject jsonObj = new JSONObject(); jsonObj.put("cname", CookieConstant.SESSION_KEY); jsonObj.put("cvalue", pool.getSession()); result.setData(jsonObj); } else { result = DataResultInfo.getInstance().failure(); result.setMessage("等待扫描"); } } } catch (Exception e) { e.printStackTrace(); } sendJsonMessage(result); } //手机扫码接口(以id和token作为用户身份登录) public String phoneScanLogin() { DataResultInfo result = null; ScanPool pool = null; if(MapUtils.isNotEmpty(PoolCache.cacheMap)) pool = PoolCache.cacheMap.get(uuid); try { if (pool == null) { result = DataResultInfo.getInstance().failure(); result.setMessage("该二维码已经失效,请重新获取"); } else { if (StringUtils.isNotEmpty(id) && StringUtils.isNotEmpty(token)) { //根据id和token查询后台,获取用户信息userBean String redisToken = redisUtil.getRedis(RedisKeyConstant.APP_TOKEN+userId); if(redisToken != null && redisToken.equals(token)){ UserBean userBean = userService.findByUserId(Long.valueOf(userId)); if (userBean != null) { String sessionId = SessionConstant.SESSION_ID_PRE + FormatUtils.password(userBean.getId() .toString()); Map cookieSession = new HashMap (); cookieSession .put(CookieConstant.SESSION_KEY, sessionId); // WrCookie.writeCookie(getResponse(),cookieSession); // 添加用户信息到redis boolean re = redisUtil.addUserInfo( RedisKeyConstant.SESSION + sessionId, BeanUtils.toBean(userBean, UserInfo.class)); getSession().setAttribute( SessionConstant.USER_INFO_WEB, BeanUtils.toBean(userBean, UserInfo.class)); getSession().setAttribute( DomainConstant.USER_CENTER_KEY, DomainConstant.USER_CENTER); pool.setSession(sessionId); pool.scanSuccess(); }else{ result = DataResultInfo.getInstance().failure(); result.setMessage("用户信息获取异常!请稍后再试"); } } else { result = DataResultInfo.getInstance().failure(); result.setExtension("11", "用户身份信息失效,请重新登录!"); } } else { result = DataResultInfo.getInstance().failure(); result.setMessage("请求参数有误!"); return "error"; } // 不能清除,否则conn方法得不到pool对象,不会进入线程休眠 // System.out.println("清除扫描过的uuid"); //PoolCache.cacheMap.remove(uuid); } } catch (Exception e) { Log4jUtil.CommonLog.error("手机扫码 后访问 异常", e); } sendJsonMessage(result); return null; } //扫码成功跳转页 public String success() { String sessionId = WrCookie.getCookie(super.getRequest(), CookieConstant.SESSION_KEY); UserInfo userInfo = redisUtil.getUserInfo(RedisKeyConstant.SESSION + sessionId); super.getRequest().setAttribute(SessionConstant.USER_INFO_WEB, userInfo); return SUCCESS; } //线程判断二维码是否超时 class ScanCounter implements Runnable { public Long timeout = 30 * 1000L; //超时时长 // 传入的对象 private String uuid; private ScanPool scanPool; public ScanCounter(String p, ScanPool scanPool) { uuid = p; this.scanPool = scanPool; } @Override public void run() { try { Thread.sleep(timeout); } catch (InterruptedException e) { e.printStackTrace(); } notifyPool(uuid, scanPool); } public synchronized void notifyPool(String uuid, ScanPool scanPool) { if (scanPool != null) scanPool.notifyPool(); } public String getUuid() { return uuid; } public void setUuid(String uuid) { this.uuid = uuid; } public ScanPool getScanPool() { return scanPool; } public void setScanPool(ScanPool scanPool) { this.scanPool = scanPool; } }
ScanPool.java(存放uuid的bean)
public class ScanPool implements Serializable{ /** * @Fields serialVersionUID : TODO(用一句话描述这个变量表示什么) */ private static final long serialVersionUID = -9117921544228636689L; private Object session ; //创建时间 private Long createTime = System.currentTimeMillis(); //登录状态 private boolean scanFlag = false; public boolean isScan(){ return scanFlag; } public void setScan(boolean scanFlag){ this.scanFlag = scanFlag; } /** * 获取扫描状态,如果还没有扫描,则等待固定秒数 * @param wiatSecond 需要等待的秒数 * @return */ public synchronized boolean getScanStatus(){ try { if(!isScan()){ //如果还未扫描,则等待 this.wait(); } if (isScan()) { System.err.println("手机扫描完成设置getScanStatus..true..........."); return true; } } catch (InterruptedException e) { e.printStackTrace(); } return false; } /** * 扫码之后设置扫码状态 * @param token * @param id */ public synchronized void scanSuccess(){ try { System.err.println("手机扫描完成setScan(true)....同时释放notifyAll(手机扫码时,根据uuid获得的scanpool对象)"); setScan(true); this.notifyAll(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public synchronized void notifyPool(){ try { this.notifyAll(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } /***********************************************/ public Long getCreateTime() { return createTime; } public void setCreateTime(Long createTime) { this.createTime = createTime; } public Object getSession() { return session; } public void setSession(Object session) { this.session = session; } }
PoolCache.java(定时清理二维码uuid的类)
public class PoolCache { // 缓存超时时间 10分钟 private static Long timeOutSecond = 10 * 60 * 1000L; // 每半小时清理一次缓存 private static Long cleanIntervalSecond = 30 * 60 * 1000L; //此map在多线程中会出现 ConcurrentModificationException //public static MapcacheMap = new HashMap (); //List //public static CopyOnWriteArrayList
扫码流程图:
流程图:
使用线程实时监听扫码状态;
用户扫描二维码相当于使用 用户名密码 在网页端登录,需要存浏览器cookie
,而用户通过使用手机扫码,直接请求服务器,登陆成功,js中得到用户数据及cookie,把cookie返给页面,再通过js存入cookie中
以上是“如何使用java实现简单扫码登录功能”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注创新互联行业资讯频道!
文章题目:如何使用java实现简单扫码登录功能
当前地址:http://cdiso.cn/article/jisjhi.html