java生成二维码扫码网页自动登录功能
找了很多资料,七七八八都试了一遍,最终写出来了这个功能。
菜鸟一枚,此文只为做笔记。
简单的一个生成二维码,通过网页确认登录,实现二维码页面跳转到主页面。
有三个servlet:
CodeServlet.java 干2件事
a:生成随机的uuid,是一个唯一标识,该标识贯穿整个流程
b:生成二维码图片,二维码信息:http://xx.xx.xx.xx:8080/xxxx/login.jsp?uuid= xxxx
LongConnectionCheckServlet.java
进行长连接轮询操作,参数为uuid,查找loginMap中是否有此uuid,如果有则停止轮询,loginMap中remove这个uuid
PhoneLoginServlet.java 干2件事
a:检测登录,查看是否有此uuid
b:登录成功后将登录信息插入到loginMap中去,uuid为key
-------- Servlet 需要配置web.xml --------
UserLoginInfoVO.java
用户登录信息存储用户名密码(其他的还可以加,我只写了简单的)
LoginUser.java
用HashMap存用户登录信息
TwoDimensionCode.java
最关键的生成二维码的类,实现QRCodeImage,需要QRCode.jar包
QRCode.jar下载地址:http://vdisk.weibo.com/s/A25JOYrYFK9xO
UserLoginInfoVO.java
public class UserLoginInfoVO {
private String userName;
private String userPass;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPass() {
return userPass;
}
public void setUserPass(String userPass) {
this.userPass = userPass;
}
}
LoginUser.java
import java.util.HashMap;
public class LoginUser {
private static HashMap<String, UserLoginInfoVO> loginMap = new HashMap<String, UserLoginInfoVO>();
private static UserLoginInfoVO userLoginInfoVO;
public static UserLoginInfoVO getVO() {
if (userLoginInfoVO == null) {
userLoginInfoVO = new UserLoginInfoVO();
}
return userLoginInfoVO;
}
public static HashMap<String, UserLoginInfoVO> getLoginMap() {
return loginMap;
}
}
TwoDimensionCode.java
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.imageio.ImageIO;
import com.swetake.util.Qrcode;
import jp.sourceforge.qrcode.QRCodeDecoder;
import jp.sourceforge.qrcode.exception.DecodingFailedException; public class TwoDimensionCode {
/**
* 生成二维码(QRCode)图片
*
* @param content
* 存储内容
* @param imgPath
* 图片路径
* @param imgType
* 图片类型
* @param output
* 输出流
* @param size
* 二维码尺寸
*/
public void encoderQRCode(String content, String imgPath) {
this.encoderQRCode(content, imgPath, "png", 7);
} public void encoderQRCode(String content, OutputStream output) {
this.encoderQRCode(content, output, "png", 7);
} public void encoderQRCode(String content, String imgPath, String imgType) {
this.encoderQRCode(content, imgPath, imgType, 7);
} public void encoderQRCode(String content, OutputStream output, String imgType) {
this.encoderQRCode(content, output, imgType, 7);
} public void encoderQRCode(String content, String imgPath, String imgType, int size) {
try {
BufferedImage bufImg = this.qRCodeCommon(content, imgType, size); File imgFile = new File(imgPath);
if (!imgFile.exists()) {
imgFile.mkdirs();
}
// 生成二维码QRCode图片
ImageIO.write(bufImg, imgType, imgFile);
} catch (Exception e) {
e.printStackTrace();
}
} public void encoderQRCode(String content, OutputStream output, String imgType, int size) {
try {
BufferedImage bufImg = this.qRCodeCommon(content, imgType, size);
// 生成二维码QRCode图片
ImageIO.write(bufImg, imgType, output);
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 生成二维码(QRCode)图片的公共方法
*
* @return BufferedImage
*/
private BufferedImage qRCodeCommon(String content, String imgType, int size) {
BufferedImage bufImg = null;
try {
Qrcode qrcode = new Qrcode();
// 设置二维码排错率,可选L(7%)、M(15%)、Q(25%)、H(30%),排错率越高可存储的信息越少,但对二维码清晰度的要求越小
qrcode.setQrcodeErrorCorrect('M');
qrcode.setQrcodeEncodeMode('B');
// 设置设置二维码尺寸,取值范围1-40,值越大尺寸越大,可存储的信息越大
qrcode.setQrcodeVersion(size);
// 获得内容的字节数组,设置编码格式
byte[] contentBytes = content.getBytes("utf-8");
// 图片尺寸
int imgSize = 67 + 12 * (size - 1);
// BufferedImage.TYPE_INT_RGB表示一个图像,该图像具有整数像素的 8 位 RGB 颜色
bufImg = new BufferedImage(imgSize, imgSize, BufferedImage.TYPE_INT_RGB); Graphics2D gs = bufImg.createGraphics();
// 设置背景颜色
gs.setBackground(Color.WHITE);
// 画矩形
gs.clearRect(0, 0, imgSize, imgSize); // 设定图像颜色 BLACK
gs.setColor(Color.BLACK);
// 设置偏移量,不设置可能导致解析出错
int pixoff = 2;
// 输出内容> 二维码
if (contentBytes.length > 0 && contentBytes.length < 800) {
// calQrcode()让字符串生成二维码。
boolean[][] codeOut = qrcode.calQrcode(contentBytes);
for (int i = 0; i < codeOut.length; i++) {
for (int j = 0; j < codeOut.length; j++) {
if (codeOut[j][i]) {
gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3);
}
}
}
} else {
throw new Exception("QRCode content bytes length = " + contentBytes.length + " not in [0, 800].");
}
gs.dispose();
bufImg.flush();
} catch (Exception e) {
e.printStackTrace();
}
return bufImg;
}
}
CodeServlet.java
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.dsjstudio.loanfront.useras.utils.TwoDimensionCode; public class CodeServlet extends HttpServlet {
private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out = response.getWriter();
// 生成唯一ID
int uuid = (int) (Math.random() * 100000);
// 二维码内容
String content = "http://localhost:8080/xxxx/index.jsp?uuid=" + uuid;
// 生成二维码
String imgName = "image_" + uuid + ".png";
String imgPath = "D:/images/" + imgName; TwoDimensionCode handler = new TwoDimensionCode();
handler.encoderQRCode(content, imgPath, "png"); System.out.println(content);
// 生成的图片访问地址
String qrCodeImg = "http://localhost:8080/images/" + imgName;
String jsonStr = "{\"uuid\":" + uuid + ",\"qrCodeImg\":\"" + qrCodeImg + "\"}";
out.print(jsonStr);
out.flush();
out.close(); }
}
LongConnectionCheckServlet.java
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.dsjstudio.loanfront.useras.controller.user.controller.LoginUser;
import com.dsjstudio.loanfront.useras.controller.user.vo.UserLoginInfoVO; public class LongConnectionCheckServlet extends HttpServlet {
private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
} protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { String uuid = request.getParameter("uuid");
String jsonStr = "";
System.out.println("in");
System.out.println("uuid:" + uuid);
long inTime = new Date().getTime();
Boolean bool = true;
while (bool) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 检测登录
UserLoginInfoVO userVo = LoginUser.getLoginMap().get(uuid);
System.out.println("userVo:" + userVo);
if (userVo != null) {
bool = false;
jsonStr = "{\"uname\":\"" + userVo.getUserName() + "\"}";
LoginUser.getLoginMap().remove(uuid);
} else {
if (new Date().getTime() - inTime > 5000) {
bool = false;
}
}
}
System.out.println("login ok : " + jsonStr);
PrintWriter out = response.getWriter();
out.print(jsonStr);
out.flush();
out.close();
} }
PhoneLoginServlet.java
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.dsjstudio.loanfront.useras.controller.user.controller.LoginUser;
import com.dsjstudio.loanfront.useras.controller.user.vo.UserLoginInfoVO; public class PhoneLoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
} protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String uuid = request.getParameter("uuid");
String uname = request.getParameter("uname");
String upwd = request.getParameter("upwd");
System.out.println(uuid);
System.out.println(uname);
System.out.println(upwd);
// TODO 验证登录
boolean bool = true;
if (bool) {
// 将登陆信息存入map
UserLoginInfoVO userVo = LoginUser.getLoginMap().get(uuid);
if (userVo == null) {
userVo = new UserLoginInfoVO();
userVo.setUserName(uname);
userVo.setUserPass(upwd);
LoginUser.getLoginMap().put(uuid, userVo);
}
}
PrintWriter out = response.getWriter();
out.print(bool);
out.flush();
out.close();
} }
两个jsp页面:
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var uuid;
//alert("1");
$.get("/dsjstudio-loan-user-as/CodeServlet", function(data, status) {
var obj = eval("(" + data + ")");
//alert("2");
//存储UUID
uuid = obj.uuid;
//显示二维码
$("#QrCodeImg").attr("src", obj.qrCodeImg);
// alert(obj.qrCodeImg);
//开始验证登录
validateLogin();
});
function validateLogin(){
$.get("/dsjstudio-loan-user-as/LongConnectionCheckServlet?uuid=" + uuid , function(data, status) {
if(data == ""){
validateLogin();
}else{
var obj = eval("(" + data + ")");
alert("欢迎您回家:" + obj.uname);
window.location.href='http://www.baidu.com';
}
});
}
});
</script>
</head>
<body>
<h1>哥么敢不敢扫一下!</h1>
<div id="divCon">
<img src="" id="QrCodeImg" />
</div>
</body>
</html>
login.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>点确认吧小伙子</title>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
//登录
function login()
$.post("/dsjstudio-loan-user-as/PhoneLoginServlet", {
uuid : $.getUrlParam('uuid'),
uname:$("#login_name").val(),
upwd:$("#login_psw").val()
}, function(data, status) {
if(data == ""){
alert("登录失败");
}else{
alert("登录成功");
}
});
}
//获取网页参数
(function($){
$.getUrlParam = function(name){
//这个正则是寻找&+url参数名字=值+&
var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
//这里是开始匹配,找到了返回对应url值,没找到返回null。
var r = window.location.search.substr(1).match(reg);
if (r!=null) return unescape(r[2]); return null;
}
})(jQuery);
</script>
</head>
<body>
<div>
<p>
<span>名称:</span>
<input type="text" id="login_name" value="lingzi">
</p>
<p>
<span>密码:</span>
<input type="password" id="login_psw" value="xxxxxxxxx">
</p>
<div>
<a href="javascript:login()">登录</a>
</div>
</div>
</body>
</html>
因为连的是本地的tomcat,所以是直接电脑上操作,二维码出来,有一个uuid打印在Console上,复制粘贴到网址上
实现效果图:

Console上uuid打印出来62951


点击登录

返回index.jsp页面查看,成功~点击确认跳转页面啦~

web.xml配置
<servlet>
<description></description>
<display-name>长连接检查登录状态</display-name>
<servlet-name>LongConnectionCheckServlet</servlet-name>
<servlet-class>com.dsjstudio.loanfront.useras.controller.user.servlet.LongConnectionCheckServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LongConnectionCheckServlet</servlet-name>
<url-pattern>/LongConnectionCheckServlet</url-pattern>
</servlet-mapping> <servlet>
<description>获取二维码图片以及uuid</description>
<display-name>CodeServlet</display-name>
<servlet-name>CodeServlet</servlet-name>
<servlet-class>com.dsjstudio.loanfront.useras.controller.user.servlet.CodeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CodeServlet</servlet-name>
<url-pattern>/CodeServlet</url-pattern>
</servlet-mapping> <servlet>
<description>手机扫描二维码之后进行登录</description>
<display-name>PhoneLoginServlet</display-name>
<servlet-name>PhoneLoginServlet</servlet-name>
<servlet-class>com.dsjstudio.loanfront.useras.controller.user.servlet.PhoneLoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PhoneLoginServlet</servlet-name>
<url-pattern>/PhoneLoginServlet</url-pattern>
</servlet-mapping>
java生成二维码扫码网页自动登录功能的更多相关文章
- 利用JAVA生成二维码
本文章整理于慕课网的学习视频<JAVA生成二维码>,如果想看视频内容请移步慕课网. 维基百科上对于二维码的解释. 二维条码是指在一维条码的基础上扩展出另一维具有可读性的条码,使用黑白矩形图 ...
- java 生成二维码、可带LOGO、可去白边
1.准备工作 所需jar包: JDK 1.6: commons-codec-1.11.jar core-2.2.jar javase-2.2.jar JDK 1.7: commons-codec- ...
- java 生成二维码后叠加LOGO并转换成base64
1.代码 见文末推荐 2.测试 测试1:生成base64码 public static void main(String[] args) throws Exception { String dat ...
- java生成二维码打印到浏览器
java生成二维码打印到浏览器 解决方法: pom.xml的依赖两个jar包: <!-- https://mvnrepository.com/artifact/com.google.zxin ...
- 二维码相关---java生成二维码名片,而且自己主动保存到手机通讯录中...
版权声明:本文为博主原创文章,未经博主credreamer 同意不得转载 违者追究法律责任. https://blog.csdn.net/lidew521/article/details/244418 ...
- java生成二维码(需导入第三方ZXing.jar包)
//这个类是用来解析,通过图片解析该图片的网页链接是什么 package util; import java.awt.Graphics2D;import java.awt.geom.AffineTra ...
- java生成二维码,读取(解析)二维码图片
二维码分为好多种,我们最常用的是qrcode类型的二维码,以下有三种生成方式以及解析方式: 附所需jar包或者js地址 第一种:依赖qrcode.jar import java.awt.Color; ...
- Java生成二维码(Java程序都可以使用)
工具类,链接:https://pan.baidu.com/s/18U399fTH5wBJPnL97pAekg 提取码:bmw7 注:里面的corejar包是使用的zxing的代码,我只是将其导出的ja ...
- JAVA生成二维码图片代码
首先需要导入 QRCode.jar 包 下载地址看这里 http://pan.baidu.com/s/1o6qRFqM import java.awt.Color;import java.awt. ...
随机推荐
- [转载]解决"command 'gcc' failed with exit status 1"错误问题
转自:https://blog.csdn.net/learn_tech/article/details/80066583 解决"command 'gcc' failed with exit ...
- 【php】单例模式和工厂模式
单例模式:防止重复实例化,避免大量的new操作,减少消耗系统和内存的资源,使得有且仅有一个实例对象 header("Content-type: text/html; charset=utf- ...
- php接口实现拖拽排序功能
列表拖拽排序是一个很常见的功能,但是后端接口如何处理却是一个令人纠结的问题 如何实现才能达到效率最高呢 先分析一个场景,假如有一个页面有十条数据,所谓的拖拽就是在这十条数据来来回回的拖,但是每次拖动都 ...
- Python之Beautiful Soup的用法
1. Beautiful Soup的简介 简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据.官方解释如下: Beautiful Soup提供一些简单的.pyt ...
- DAY20 常用模块(三)
一.加密模块 1.加密方式: 1.有解密的加密方式 2.无解密的加密方式,碰撞检查 1.不同数据加密后的结果一定不一致 2.相同数据的加密结果一定是一致 2.hashlib模块 1.基本使用 ciph ...
- python 学习笔记 2 ----> dive into python 3
Python Shell idle的使用 >>> >>>help() ----> help> 可以在help这个工具中查找Python内置函数的文档等等 ...
- 使用npm私有服务器保存公司内部强业务类型组件(一):npm私有服务器搭建
1:安装centOS虚拟机 2:安装完成虚拟机后完成后开启系统网卡: 进入到/etc/sysconfig/network-scprits/ 打开ifcfg-ens33文件 找到 ONBOOT=NO 改 ...
- 1GB pages can only be allocated at boot time using hugepages= and not freed afterwards
2018-6-27 9:12:38 https://stackoverflow.com/questions/26385554/error-setting-nr-hugepages-via-sysfs ...
- mysql将查询结果导出
一.首先确认当前数据库设置导出是允许的 show variables like '%secure%'; 如果是null则代表不允许,这时可以用命令修改,或者直接修改数据库配置文件my.ini,在其中添 ...
- js的call和apply区别
call和apply都是改变了this的指针. obj.call(newObj, arg1, arg2, ...); obj.apply(newObj, [arg1, arg2, ...]); 上面的 ...