Java实现简单二维码制作
来源:互联网 发布:unity3d树叶是方形的 编辑:程序博客网 时间:2024/06/05 22:50
实现流程:
pc端:
1:打开二维码登录网页index.html
2:index.html调用GetQrCodeServlet
3:GetQrCodeServlet干2件事
a:生成随机的uuid,是一个唯一标识,该标识贯穿整个流程
b:生成二维码图片,二维码信息:http://60.28.201.37:8380/QrCodeLoginPro/Login.html?uuid=" + uuid
4:index页面展示二维码
5:index页面调用LongConnectionCheckServlet进行长连接轮询操作,参数为uuid
6:LongConnectionCheckServlet只干1件事
a:拿到uuid后循环检查loginUserMap中uuid是否不为null。
7:如果为null则代表没有登录,index.html将继续进行轮询
ps: LongConnectionCheckServlet 一个长连接请求检测登录状态
loginUserMap 是一个静态的map结构的登录池,uuid为key , 登录信息为value
手机端:
1:扫描pc端的二维码
2:打开二维码中的网页 http://60.28.201.37:8380/QrCodeLoginPro/Login.html?uuid=" + uuid
3:登录,将uname upwd uuid 传递给登录程序PhoneLoginServlet
4:PhoneLoginServlet干2件事
a:检测登录
b:登录成功后将登录信息插入到loginUserMap中去,uuid为key
pc端:
1:继续轮询检测uuid中是否为null
2:登录后的uuid中就不为null了,此时LongConnectionCheckServlet停止循环,返回登录状态。
代码:
cn.kuwo下的3个servlet
package
cn.kuwo;
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
cn.kuwo.util.TwoDimensionCode;
/**
* 生成二维码图片以及uuid
* @author zijuntang
*
*/
public
class
GetQrCodeServlet
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://60.28.201.37:8380/QrCodeLoginPro/Login.html?uuid="
+ uuid;
//生成二维码
String imgName = uuid +
"_"
+ (
int
) (
new
Date().getTime() /
1000
) +
".png"
;
String imgPath =
"/home/web/apache/htdocs/QrCodeLogin/"
+ imgName;
TwoDimensionCode handler =
new
TwoDimensionCode();
handler.encoderQRCode(content, imgPath,
"png"
);
//生成的图片访问地址
String qrCodeImg =
"http://60.28.201.37/QrCodeLogin/"
+ imgName;
String jsonStr =
"{\"uuid\":"
+ uuid +
",\"qrCodeImg\":\""
+ qrCodeImg +
"\"}"
;
out.print(jsonStr);
out.flush();
out.close();
}
}
package
cn.kuwo;
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
cn.kuwo.vo.LoginUserVo;
import
cn.kuwo.vo.UserVo;
/**
* 用长连接,检查登录状态
* @author zijuntang
*
*/
public
class
LongConnectionCheckServlet
extends
HttpServlet {
private
static
final
long
serialVersionUID = 1L;
public
void
doGet(HttpServletRequest request, HttpServletResponse response)
throws
ServletException, IOException {
doPost(request, response);
}
public
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(
1000
);
}
catch
(InterruptedException e) {
e.printStackTrace();
}
//检测登录
UserVo userVo = LoginUserVo.getLoginUserMap().get(uuid);
System.out.println(
"userVo:"
+ userVo);
if
(userVo !=
null
){
bool =
false
;
jsonStr =
"{\"uname\":\""
+userVo.getUname()+
"\"}"
;
LoginUserVo.getLoginUserMap().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();
}
}
package
cn.kuwo;
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
cn.kuwo.vo.LoginUserVo;
import
cn.kuwo.vo.UserVo;
/**
* 二维码手机端登录
* @author zijuntang
*
*/
public
class
PhoneLoginServlet
extends
HttpServlet {
private
static
final
long
serialVersionUID = 1L;
public
PhoneLoginServlet() {
super
();
// TODO Auto-generated constructor stub
}
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
UserVo userVo = LoginUserVo.getLoginUserMap().get(uuid);
if
(userVo ==
null
){
userVo =
new
UserVo();
userVo.setUname(uname);
userVo.setUpwd(upwd);
LoginUserVo.getLoginUserMap().put(uuid, userVo);
}
}
PrintWriter out = response.getWriter();
out.print(bool);
out.flush();
out.close();
}
}
cn.kuwo.util包下的生成二维码的封装类
package
cn.kuwo.util;
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
jp.sourceforge.qrcode.QRCodeDecoder;
import
jp.sourceforge.qrcode.exception.DecodingFailedException;
import
com.swetake.util.Qrcode;
public
class
TwoDimensionCode {
/**
* 生成二维码(QRCode)图片
* @param content 存储内容
* @param imgPath 图片路径
*/
public
void
encoderQRCode(String content, String imgPath) {
this
.encoderQRCode(content, imgPath,
"png"
,
7
);
}
/**
* 生成二维码(QRCode)图片
* @param content 存储内容
* @param output 输出流
*/
public
void
encoderQRCode(String content, OutputStream output) {
this
.encoderQRCode(content, output,
"png"
,
7
);
}
/**
* 生成二维码(QRCode)图片
* @param content 存储内容
* @param imgPath 图片路径
* @param imgType 图片类型
*/
public
void
encoderQRCode(String content, String imgPath, String imgType) {
this
.encoderQRCode(content, imgPath, imgType,
7
);
}
/**
* 生成二维码(QRCode)图片
* @param content 存储内容
* @param output 输出流
* @param imgType 图片类型
*/
public
void
encoderQRCode(String content, OutputStream output, String imgType) {
this
.encoderQRCode(content, output, imgType,
7
);
}
/**
* 生成二维码(QRCode)图片
* @param content 存储内容
* @param imgPath 图片路径
* @param imgType 图片类型
* @param size 二维码尺寸
*/
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();
}
}
/**
* 生成二维码(QRCode)图片
* @param content 存储内容
* @param output 输出流
* @param imgType 图片类型
* @param size 二维码尺寸
*/
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)图片的公共方法
* @param content 存储内容
* @param imgType 图片类型
* @param size 二维码尺寸
* @return
*/
private
BufferedImage qRCodeCommon(String content, String imgType,
int
size) {
BufferedImage bufImg =
null
;
try
{
Qrcode qrcodeHandler =
new
Qrcode();
// 设置二维码排错率,可选L(7%)、M(15%)、Q(25%)、H(30%),排错率越高可存储的信息越少,但对二维码清晰度的要求越小
qrcodeHandler.setQrcodeErrorCorrect(
'M'
);
qrcodeHandler.setQrcodeEncodeMode(
'B'
);
// 设置设置二维码尺寸,取值范围1-40,值越大尺寸越大,可存储的信息越大
qrcodeHandler.setQrcodeVersion(size);
// 获得内容的字节数组,设置编码格式
byte
[] contentBytes = content.getBytes(
"utf-8"
);
// 图片尺寸
int
imgSize =
67
+
12
* (size -
1
);
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
) {
boolean
[][] codeOut = qrcodeHandler.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;
}
/**
* 解析二维码(QRCode)
* @param imgPath 图片路径
* @return
*/
public
String decoderQRCode(String imgPath) {
// QRCode 二维码图片的文件
File imageFile =
new
File(imgPath);
BufferedImage bufImg =
null
;
String content =
null
;
try
{
bufImg = ImageIO.read(imageFile);
QRCodeDecoder decoder =
new
QRCodeDecoder();
content =
new
String(decoder.decode(
new
TwoDimensionCodeImage(bufImg)),
"utf-8"
);
}
catch
(IOException e) {
System.out.println(
"Error: "
+ e.getMessage());
e.printStackTrace();
}
catch
(DecodingFailedException dfe) {
System.out.println(
"Error: "
+ dfe.getMessage());
dfe.printStackTrace();
}
return
content;
}
/**
* 解析二维码(QRCode)
* @param input 输入流
* @return
*/
public
String decoderQRCode(InputStream input) {
BufferedImage bufImg =
null
;
String content =
null
;
try
{
bufImg = ImageIO.read(input);
QRCodeDecoder decoder =
new
QRCodeDecoder();
content =
new
String(decoder.decode(
new
TwoDimensionCodeImage(bufImg)),
"utf-8"
);
}
catch
(IOException e) {
System.out.println(
"Error: "
+ e.getMessage());
e.printStackTrace();
}
catch
(DecodingFailedException dfe) {
System.out.println(
"Error: "
+ dfe.getMessage());
dfe.printStackTrace();
}
return
content;
}
public
static
void
main(String[] args) {
String imgPath =
"D:/aaa/Michael_QRCode.png"
;
String encoderContent =
"http://60.28.201.37:8380/QrCodeLoginPro/Login.html"
;
TwoDimensionCode handler =
new
TwoDimensionCode();
handler.encoderQRCode(encoderContent, imgPath,
"png"
);
/*
System.out.println("========encoder success");
String decoderContent = handler.decoderQRCode(imgPath);
System.out.println("解析结果如下:");
System.out.println(decoderContent);
System.out.println("========decoder success!!!");
*/
}
}
package
cn.kuwo.util;
import
java.awt.image.BufferedImage;
import
jp.sourceforge.qrcode.data.QRCodeImage;
public
class
TwoDimensionCodeImage
implements
QRCodeImage {
BufferedImage bufImg;
public
TwoDimensionCodeImage(BufferedImage bufImg) {
this
.bufImg = bufImg;
}
@Override
public
int
getHeight() {
return
bufImg.getHeight();
}
@Override
public
int
getPixel(
int
x,
int
y) {
return
bufImg.getRGB(x, y);
}
@Override
public
int
getWidth() {
return
bufImg.getWidth();
}
}
cn.kuwo.vo下的2个数据层
package
cn.kuwo.vo;
import
java.util.HashMap;
public
class
LoginUserVo {
private
static
HashMap<String, UserVo> loginUserMap =
new
HashMap<String, UserVo>();
private
static
LoginUserVo loginUserVo;
public
static
LoginUserVo getVo(){
if
(loginUserVo ==
null
){
loginUserVo =
new
LoginUserVo();
}
return
loginUserVo;
}
public
static
HashMap<String, UserVo> getLoginUserMap() {
return
loginUserMap;
}
}
package
cn.kuwo.vo;
public
class
UserVo {
private
String uname;
private
String upwd;
public
String getUname() {
return
uname;
}
public
void
setUname(String uname) {
this
.uname = uname;
}
public
String getUpwd() {
return
upwd;
}
public
void
setUpwd(String upwd) {
this
.upwd = upwd;
}
}
2个网页
<!DOCTYPE html>
<html>
<head>
<meta charset=
"UTF-8"
>
<title>Insert title here</title>
</head>
<script type=
"text/javascript"
src=
"js/jquery-1.11.0.min.js"
></script>
<body>
<div id=
"divCon"
>
<img src=
""
id=
"QrCodeImg"
/>
</div>
</body>
<script type=
"text/javascript"
>
$(document).ready(function() {
var uuid;
$.get(
"/QrCodeLoginPro/GetQrCodeServlet"
, function(data, status) {
var obj = eval(
"("
+ data +
")"
);
//存储UUID
uuid = obj.uuid;
//显示二维码
$(
"#QrCodeImg"
).attr(
"src"
, obj.qrCodeImg);
//开始验证登录
validateLogin();
});
function validateLogin(){
$.get(
"/QrCodeLoginPro/LongConnectionCheckServlet?uuid="
+ uuid , function(data, status) {
if
(data ==
""
){
validateLogin();
}
else
{
var obj = eval(
"("
+ data +
")"
);
alert(
"登录成功了:"
+ obj.uname);
}
});
}
});
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset=
"UTF-8"
>
<title>Insert title here</title>
</head>
<style>
.l_m_l {
float
: left;
font-size: 14px;
padding: 5px
0
0
0
;
width: 330px;
color: #
414141
;
}
.l_m_linput {
height: 31px;
position: relative;
width: 300px;
margin-bottom: 21px;
}
.l_m_linput span {
float
: left;
width: 78px;
text-align: right;
line-height: 31px;
}
input {
float
: left;
width: 195px;
height: 24px;
line-height: 24px;
background: #f2f2f2;
border: 1px solid #c4c4c4;
padding: 2px 22px 2px 2px;
}
.l_mimacon {
position: absolute;
top: 6px;
right: 6px;
width: 15px;
height: 17px;
background: url(img/l_mimacon.png)
no-repeat;
}
.l_peoplecon {
position: absolute;
top: 7px;
right: 6px;
width: 15px;
height: 15px;
background: url(img/l_peoplecon.png)
no-repeat;
}
.l_m_lload a {
display: block;
width: 154px;
height: 40px;
background:
url(img/l_loadingbtn.png)
no-repeat;
margin:
0
auto;
line-height: 40px;
text-align: center;
font-size: 18px;
color: #52340c;
text-decoration: none;
}
</style>
<script type=
"text/javascript"
src=
"js/jquery-1.11.0.min.js"
></script>
<body style=
"background-color: #333333"
>
<div style=
"margin-left: 100px;"
><img src=
"img/logo.png"
/></div>
<div >
<p
class
=
"l_m_linput"
>
<span><font color=
"#fff"
>用户名:</font></span><input type=
"text"
id=
"login_name"
value=
"zijuntang"
><em
class
=
"l_peoplecon"
></em>
</p>
<p
class
=
"l_m_linput"
>
<span><font color=
"#fff"
>密码:</font></span><input type=
"password"
id=
"login_psw"
value=
"tangzijun"
><em
class
=
"l_mimacon"
></em>
</p>
<div
class
=
"l_m_linput2"
></div>
<div
class
=
"l_m_lload"
>
<a href=
"javascript:login();"
>登录</a>
</div>
</div>
</body>
<script type=
"text/javascript"
>
//登录
function login(){
$.post(
"/QrCodeLoginPro/PhoneLoginServlet"
, {
uuid : $.getUrlParam(
'uuid'
),
uname:$(
"#login_name"
).val(),
upwd:$(
"#login_psw"
).val()
}, function(data, status) {
if
(data ==
""
){
alert(
"登录失败"
);
}
else
{
alert(
"登录成功"
);
}
});
}
//获取网页参数
(function($){
$.getUrlParam = function(name){
var reg =
new
RegExp(
"(^|&)"
+ name +
"=([^&]*)(&|$)"
);
var r = window.location.search.substr(
1
).match(reg);
if
(r!=
null
)
return
unescape(r[
2
]);
return
null
;
}
})(jQuery);
</script>
</html>
web.xml配置文件
<?xml version=
"1.0"
encoding=
"UTF-8"
?>
<web-app xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns=
"http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation=
"http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id=
"WebApp_ID"
version=
"2.5"
>
<display-name>QrCodeLoginPro</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<servlet>
<description></description>
<display-name>长连接检查登录状态</display-name>
<servlet-name>LongConnectionCheckServlet</servlet-name>
<servlet-
class
>cn.kuwo.LongConnectionCheckServlet</servlet-
class
>
</servlet>
<servlet-mapping>
<servlet-name>LongConnectionCheckServlet</servlet-name>
<url-pattern>/LongConnectionCheckServlet</url-pattern>
</servlet-mapping>
<servlet>
<description>获取二维码图片以及uuid</description>
<display-name>GetQrCodeServlet</display-name>
<servlet-name>GetQrCodeServlet</servlet-name>
<servlet-
class
>cn.kuwo.GetQrCodeServlet</servlet-
class
>
</servlet>
<servlet-mapping>
<servlet-name>GetQrCodeServlet</servlet-name>
<url-pattern>/GetQrCodeServlet</url-pattern>
</servlet-mapping>
<servlet>
<description>手机扫描二维码之后进行登录</description>
<display-name>PhoneLoginServlet</display-name>
<servlet-name>PhoneLoginServlet</servlet-name>
<servlet-
class
>cn.kuwo.PhoneLoginServlet</servlet-
class
>
</servlet>
<servlet-mapping>
<servlet-name>PhoneLoginServlet</servlet-name>
<url-pattern>/PhoneLoginServlet</url-pattern>
</servlet-mapping>
</web-app>
此外还需要1个二维码开源包:QRCode.jar
- Java实现简单二维码制作
- 简单二维码制作JAVA实现
- Java实现简单二维码制作
- java实现二维码制作
- Java实现二维码制作
- java简单实现二维码
- JAVA简单二维码实现
- Java二维码的制作
- Java 制作二维码代码
- Java 制作二维码
- 简单实现二维码扫描
- 简单实现二维码扫描
- 简单实现二维码生成器
- 简单实现二维码
- 简单学习二维码生成步骤--java代码实现
- 简单制作属于自己的二维码
- java实现生成二维码
- java实现二维码生成
- 31、互斥锁与进程间通信
- 腾讯大牛教你web前后端漏洞分析与防御-点击劫持,传输安全
- k-近邻算法
- RxJava + Retrofit + OKHttp + RxLifecycle进一步封装网络
- (HYSBZ
- Java实现简单二维码制作
- YAML
- 【leetcode】第55题 Jump Game 题目+解析+代码
- ICMP&&IP&&ARP
- spring + spring mvc + mybatis 整合框架
- c#基础:非泛型集合系列
- Android 基础 -- 生命周期和启动模式实践总结
- SqueezeNet模型详解
- 运维基础——Zabbix 设置Redis监控