博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
通过Servlet生成验证码图片
阅读量:6504 次
发布时间:2019-06-24

本文共 11559 字,大约阅读时间需要 38 分钟。

创建一个DrawImage Servlet,用来生成验证码图片:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
package 
gacl.response.study;
import 
java.awt.Color;
import 
java.awt.Font;
import 
java.awt.Graphics;
import 
java.awt.Graphics2D;
import 
java.awt.image.BufferedImage;
import 
java.io.IOException;
import 
java.util.Random;
import 
javax.imageio.ImageIO;
import 
javax.servlet.ServletException;
import 
javax.servlet.http.HttpServlet;
import 
javax.servlet.http.HttpServletRequest;
import 
javax.servlet.http.HttpServletResponse;
/**
 
* 生成随机图片,用来作为验证码
 
*/
public 
class 
DrawImage 
extends 
HttpServlet {
    
private 
static 
final 
long 
serialVersionUID = 3038623696184546092L;
     
    
public 
static 
final 
int 
WIDTH = 
120
;
//生成的图片的宽度
    
public 
static 
final 
int 
HEIGHT = 
30
;
//生成的图片的高度
 
    
public 
void 
doGet(HttpServletRequest request, HttpServletResponse response)
            
throws 
ServletException, IOException {
        
this
.doPost(request, response);
    
}
 
    
public 
void 
doPost(HttpServletRequest request, HttpServletResponse response)
            
throws 
ServletException, IOException {
        
String createTypeFlag = request.getParameter(
"createTypeFlag"
);
//接收客户端传递的createTypeFlag标识
        
//1.在内存中创建一张图片
        
BufferedImage bi = 
new 
BufferedImage(WIDTH, HEIGHT,BufferedImage.TYPE_INT_RGB);
        
//2.得到图片
        
Graphics g = bi.getGraphics();
        
//3.设置图片的背影色
        
setBackGround(g);
        
//4.设置图片的边框
        
setBorder(g);
        
//5.在图片上画干扰线
        
drawRandomLine(g);
        
//6.写在图片上随机数
        
//String random = drawRandomNum((Graphics2D) g,"ch");//生成中文验证码图片
        
//String random = drawRandomNum((Graphics2D) g,"nl");//生成数字和字母组合的验证码图片
        
//String random = drawRandomNum((Graphics2D) g,"n");//生成纯数字的验证码图片
        
//String random = drawRandomNum((Graphics2D) g,"l");//生成纯字母的验证码图片
        
String random = drawRandomNum((Graphics2D) g,createTypeFlag);
//根据客户端传递的createTypeFlag标识生成验证码图片
        
//7.将随机数存在session中
        
request.getSession().setAttribute(
"checkcode"
, random);
        
//8.设置响应头通知浏览器以图片的形式打开
        
response.setContentType(
"image/jpeg"
);
//等同于response.setHeader("Content-Type", "image/jpeg");
        
//9.设置响应头控制浏览器不要缓存
        
response.setDateHeader(
"expries"
, -
1
);
        
response.setHeader(
"Cache-Control"
"no-cache"
);
        
response.setHeader(
"Pragma"
"no-cache"
);
        
//10.将图片写给浏览器
        
ImageIO.write(bi, 
"jpg"
, response.getOutputStream());
    
}
 
    
/**
     
* 设置图片的背景色
     
* @param g
     
*/
    
private 
void 
setBackGround(Graphics g) {
        
// 设置颜色
        
g.setColor(Color.WHITE);
        
// 填充区域
        
g.fillRect(
0
0
, WIDTH, HEIGHT);
    
}
 
    
/**
     
* 设置图片的边框
     
* @param g
     
*/
    
private 
void 
setBorder(Graphics g) {
        
// 设置边框颜色
        
g.setColor(Color.BLUE);
        
// 边框区域
        
g.drawRect(
1
1
, WIDTH - 
2
, HEIGHT - 
2
);
    
}
 
    
/**
     
* 在图片上画随机线条
     
* @param g
     
*/
    
private 
void 
drawRandomLine(Graphics g) {
        
// 设置颜色
        
g.setColor(Color.GREEN);
        
// 设置线条个数并画线
        
for 
(
int 
i = 
0
; i < 
5
; i++) {
            
int 
x1 = 
new 
Random().nextInt(WIDTH);
            
int 
y1 = 
new 
Random().nextInt(HEIGHT);
            
int 
x2 = 
new 
Random().nextInt(WIDTH);
            
int 
y2 = 
new 
Random().nextInt(HEIGHT);
            
g.drawLine(x1, y1, x2, y2);
        
}
    
}
 
    
/**
     
* 画随机字符
     
* @param g
     
* @param createTypeFlag
     
* @return
     
* String... createTypeFlag是可变参数,
     
* Java1.5增加了新特性:可变参数:适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理。注意:可变参数必须位于最后一项
     
*/
    
private 
String drawRandomNum(Graphics2D g,String... createTypeFlag) {
        
// 设置颜色
        
g.setColor(Color.RED);
        
// 设置字体
        
g.setFont(
new 
Font(
"宋体"
, Font.BOLD, 
20
));
        
//常用的中国汉字
        
String baseChineseChar = 
"\u7684\u4e00\u4e86\u662f\u6211\u4e0d\u5728\u4eba\u4eec\u6709\u6765\u4ed6\u8fd9\u4e0a\u7740\u4e2a\u5730\u5230\u5927\u91cc\u8bf4\u5c31\u53bb\u5b50\u5f97\u4e5f\u548c\u90a3\u8981\u4e0b\u770b\u5929\u65f6\u8fc7\u51fa\u5c0f\u4e48\u8d77\u4f60\u90fd\u628a\u597d\u8fd8\u591a\u6ca1\u4e3a\u53c8\u53ef\u5bb6\u5b66\u53ea\u4ee5\u4e3b\u4f1a\u6837\u5e74\u60f3\u751f\u540c\u8001\u4e2d\u5341\u4ece\u81ea\u9762\u524d\u5934\u9053\u5b83\u540e\u7136\u8d70\u5f88\u50cf\u89c1\u4e24\u7528\u5979\u56fd\u52a8\u8fdb\u6210\u56de\u4ec0\u8fb9\u4f5c\u5bf9\u5f00\u800c\u5df1\u4e9b\u73b0\u5c71\u6c11\u5019\u7ecf\u53d1\u5de5\u5411\u4e8b\u547d\u7ed9\u957f\u6c34\u51e0\u4e49\u4e09\u58f0\u4e8e\u9ad8\u624b\u77e5\u7406\u773c\u5fd7\u70b9\u5fc3\u6218\u4e8c\u95ee\u4f46\u8eab\u65b9\u5b9e\u5403\u505a\u53eb\u5f53\u4f4f\u542c\u9769\u6253\u5462\u771f\u5168\u624d\u56db\u5df2\u6240\u654c\u4e4b\u6700\u5149\u4ea7\u60c5\u8def\u5206\u603b\u6761\u767d\u8bdd\u4e1c\u5e2d\u6b21\u4eb2\u5982\u88ab\u82b1\u53e3\u653e\u513f\u5e38\u6c14\u4e94\u7b2c\u4f7f\u5199\u519b\u5427\u6587\u8fd0\u518d\u679c\u600e\u5b9a\u8bb8\u5feb\u660e\u884c\u56e0\u522b\u98de\u5916\u6811\u7269\u6d3b\u90e8\u95e8\u65e0\u5f80\u8239\u671b\u65b0\u5e26\u961f\u5148\u529b\u5b8c\u5374\u7ad9\u4ee3\u5458\u673a\u66f4\u4e5d\u60a8\u6bcf\u98ce\u7ea7\u8ddf\u7b11\u554a\u5b69\u4e07\u5c11\u76f4\u610f\u591c\u6bd4\u9636\u8fde\u8f66\u91cd\u4fbf\u6597\u9a6c\u54ea\u5316\u592a\u6307\u53d8\u793e\u4f3c\u58eb\u8005\u5e72\u77f3\u6ee1\u65e5\u51b3\u767e\u539f\u62ff\u7fa4\u7a76\u5404\u516d\u672c\u601d\u89e3\u7acb\u6cb3\u6751\u516b\u96be\u65e9\u8bba\u5417\u6839\u5171\u8ba9\u76f8\u7814\u4eca\u5176\u4e66\u5750\u63a5\u5e94\u5173\u4fe1\u89c9\u6b65\u53cd\u5904\u8bb0\u5c06\u5343\u627e\u4e89\u9886\u6216\u5e08\u7ed3\u5757\u8dd1\u8c01\u8349\u8d8a\u5b57\u52a0\u811a\u7d27\u7231\u7b49\u4e60\u9635\u6015\u6708\u9752\u534a\u706b\u6cd5\u9898\u5efa\u8d76\u4f4d\u5531\u6d77\u4e03\u5973\u4efb\u4ef6\u611f\u51c6\u5f20\u56e2\u5c4b\u79bb\u8272\u8138\u7247\u79d1\u5012\u775b\u5229\u4e16\u521a\u4e14\u7531\u9001\u5207\u661f\u5bfc\u665a\u8868\u591f\u6574\u8ba4\u54cd\u96ea\u6d41\u672a\u573a\u8be5\u5e76\u5e95\u6df1\u523b\u5e73\u4f1f\u5fd9\u63d0\u786e\u8fd1\u4eae\u8f7b\u8bb2\u519c\u53e4\u9ed1\u544a\u754c\u62c9\u540d\u5440\u571f\u6e05\u9633\u7167\u529e\u53f2\u6539\u5386\u8f6c\u753b\u9020\u5634\u6b64\u6cbb\u5317\u5fc5\u670d\u96e8\u7a7f\u5185\u8bc6\u9a8c\u4f20\u4e1a\u83dc\u722c\u7761\u5174\u5f62\u91cf\u54b1\u89c2\u82e6\u4f53\u4f17\u901a\u51b2\u5408\u7834\u53cb\u5ea6\u672f\u996d\u516c\u65c1\u623f\u6781\u5357\u67aa\u8bfb\u6c99\u5c81\u7ebf\u91ce\u575a\u7a7a\u6536\u7b97\u81f3\u653f\u57ce\u52b3\u843d\u94b1\u7279\u56f4\u5f1f\u80dc\u6559\u70ed\u5c55\u5305\u6b4c\u7c7b\u6e10\u5f3a\u6570\u4e61\u547c\u6027\u97f3\u7b54\u54e5\u9645\u65e7\u795e\u5ea7\u7ae0\u5e2e\u5566\u53d7\u7cfb\u4ee4\u8df3\u975e\u4f55\u725b\u53d6\u5165\u5cb8\u6562\u6389\u5ffd\u79cd\u88c5\u9876\u6025\u6797\u505c\u606f\u53e5\u533a\u8863\u822c\u62a5\u53f6\u538b\u6162\u53d4\u80cc\u7ec6"
;
        
//数字和字母的组合
        
String baseNumLetter = 
"0123456789ABCDEFGHJKLMNOPQRSTUVWXYZ"
;
        
//纯数字
        
String baseNum = 
"0123456789"
;
        
//纯字母
        
String baseLetter = 
"ABCDEFGHJKLMNOPQRSTUVWXYZ"
;
        
//createTypeFlag[0]==null表示没有传递参数
        
if 
(createTypeFlag.length > 
0 
&& 
null 
!= createTypeFlag[
0
]) {
            
if 
(createTypeFlag[
0
].equals(
"ch"
)) {
                
// 截取汉字
                
return 
createRandomChar(g, baseChineseChar);
            
}
else 
if 
(createTypeFlag[
0
].equals(
"nl"
)) {
                
// 截取数字和字母的组合
                
return 
createRandomChar(g, baseNumLetter);
            
}
else 
if 
(createTypeFlag[
0
].equals(
"n"
)) {
                
// 截取数字
                
return 
createRandomChar(g, baseNum);
            
}
else 
if 
(createTypeFlag[
0
].equals(
"l"
)) {
                
// 截取字母
                
return 
createRandomChar(g, baseLetter);
            
}
        
}
else 
{
            
// 默认截取数字和字母的组合
            
return 
createRandomChar(g, baseNumLetter);
        
}
         
        
return 
""
;
    
}
 
    
/**
     
* 创建随机字符
     
* @param g
     
* @param baseChar
     
* @return 随机字符
     
*/
    
private 
String createRandomChar(Graphics2D g,String baseChar) {
        
StringBuffer sb = 
new 
StringBuffer();
        
int 
x = 
5
;
        
String ch =
""
;
        
// 控制字数
        
for 
(
int 
i = 
0
; i < 
4
; i++) {
            
// 设置字体旋转角度
            
int 
degree = 
new 
Random().nextInt() % 
30
;
            
ch = baseChar.charAt(
new 
Random().nextInt(baseChar.length())) + 
""
;
            
sb.append(ch);
            
// 正向角度
            
g.rotate(degree * Math.PI / 
180
, x, 
20
);
            
g.drawString(ch, x, 
20
);
            
// 反向角度
            
g.rotate(-degree * Math.PI / 
180
, x, 
20
);
            
x += 
30
;
        
}
        
return 
sb.toString();
    
}
}

二、在Form表单中使用验证码图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<
html
>
  
<
head
>
    
<
title
>在Form表单中使用验证码</
title
>
    
<
script 
type
=
"text/javascript"
>
    
//刷新验证码
    
function changeImg(){
        
document.getElementById("validateCodeImg").src="${pageContext.request.contextPath}/servlet/DrawImage?"+Math.random();
    
}
    
</
script
>
  
</
head
>
   
  
<
body
>
        
<
form 
action
=
"${pageContext.request.contextPath}/servlet/CheckServlet" 
method
=
"post"
>
            
验证码:<
input 
type
=
"text" 
name
=
"validateCode"
/>
            
<
img 
alt
=
"验证码看不清,换一张" 
src
=
"${pageContext.request.contextPath}/servlet/DrawImage" 
id
=
"validateCodeImg" 
onclick
=
"changeImg()"
>
            
<
a 
href
=
"javascript:void(0)" 
onclick
=
"changeImg()"
>看不清,换一张</
a
>
            
<
br
/>
            
<
input 
type
=
"submit" 
value
=
"提交"
>
        
</
form
>
  
</
body
>
</
html
>

DrawImage Servlet除了可以生成的字母和数字的组合的验证码图片之外,还可以生成汉字,纯数字,纯字母的验证码图片,只需要向DrawImage Servlet传递约定好的生成标识符参数即可,如下所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<
html
>
  
<
head
>
    
<
title
>在Form表单中使用验证码</
title
>
    
<
script 
type
=
"text/javascript"
>
    
//刷新验证码
    
function changeImg(obj,createTypeFlag){
        
document.getElementById(obj.id).src="${pageContext.request.contextPath}/servlet/DrawImage?createTypeFlag="+createTypeFlag+"&"+Math.random();
    
}
    
</
script
>
  
</
head
>
   
  
<
body
>
        
<
form 
action
=
"${pageContext.request.contextPath}/servlet/CheckServlet" 
method
=
"post"
>
            
数字字母混合验证码:<
input 
type
=
"text" 
name
=
"validateCode"
/>
            
<
img 
alt
=
"验证码看不清,换一张" 
src
=
"${pageContext.request.contextPath}/servlet/DrawImage" 
id
=
"validateCodeImg1" 
onclick
=
"changeImg(this,'nl')"
>
            
<
br
/>
            
中文验证码:<
input 
type
=
"text" 
name
=
"validateCode"
/>
            
<
img 
alt
=
"验证码看不清,换一张" 
src
=
"${pageContext.request.contextPath}/servlet/DrawImage?createTypeFlag=ch" 
id
=
"validateCodeImg2" 
onclick
=
"changeImg(this,'ch')"
>
            
<
br
/>
            
英文验证码:<
input 
type
=
"text" 
name
=
"validateCode"
/>
            
<
img 
alt
=
"验证码看不清,换一张" 
src
=
"${pageContext.request.contextPath}/servlet/DrawImage?createTypeFlag=l" 
id
=
"validateCodeImg3" 
onclick
=
"changeImg(this,'l')"
>
            
<
br
/>
            
数字验证码:<
input 
type
=
"text" 
name
=
"validateCode"
/>
            
<
img 
alt
=
"验证码看不清,换一张" 
src
=
"${pageContext.request.contextPath}/servlet/DrawImage?createTypeFlag=n" 
id
=
"validateCodeImg4" 
onclick
=
"changeImg(this,'n')"
>
            
<
br
/>
            
<
input 
type
=
"submit" 
value
=
"提交"
>
        
</
form
>
  
</
body
>
</
html
>

三、服务器端对form表单提交上来的验证码处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package 
gacl.response.study;
import 
java.io.IOException;
import 
javax.servlet.ServletException;
import 
javax.servlet.http.HttpServlet;
import 
javax.servlet.http.HttpServletRequest;
import 
javax.servlet.http.HttpServletResponse;
/**
 
* @author gacl
 
* 服务器端接收到验证码后的处理
 
*/
public 
class 
CheckServlet 
extends 
HttpServlet {
    
public 
void 
doGet(HttpServletRequest request, HttpServletResponse response)
            
throws 
ServletException, IOException {
        
String clientCheckcode = request.getParameter(
"validateCode"
);
//接收客户端浏览器提交上来的验证码
        
String serverCheckcode = (String) request.getSession().getAttribute(
"checkcode"
);
//从服务器端的session中取出验证码
        
if 
(clientCheckcode.equals(serverCheckcode)) {
//将客户端验证码和服务器端验证比较,如果相等,则表示验证通过
            
System.out.println(
"验证码验证通过!"
);
        
}
else 
{
            
System.out.println(
"验证码验证失败!"
);
        
}
    
}
 
    
public 
void 
doPost(HttpServletRequest request, HttpServletResponse response)
            
throws 
ServletException, IOException {
        
doGet(request, response);
    
}
 
}

http://www.cnblogs.com/xdp-gacl/p/3798190.html

本文转自yunlielai51CTO博客,原文链接:http://blog.51cto.com/4925054/1723064,如需转载请自行联系原作者

你可能感兴趣的文章
熬夜写了一个小游戏,向SpaceX聊表敬意
查看>>
身份证工具类
查看>>
JPA增删改查,
查看>>
apache 开启 gzip 压缩服务
查看>>
python mysql
查看>>
开源 免费 java CMS - FreeCMS1.5-建站向导
查看>>
Selenium的延迟等待
查看>>
jquery 1.6以上版本 全选
查看>>
AppCan 学习
查看>>
flask框架
查看>>
《疯狂Java讲义》学习笔记(十)异常处理
查看>>
Lua(Codea) 中 table.insert 越界错误原因分析
查看>>
ELK 5.x日志分析 (二) Elasticserach 5.2 安装
查看>>
一次奇怪的AP注册异常问题处理
查看>>
TableStore: 海量结构化数据分层存储方案
查看>>
Unity 4.x游戏开发技巧集锦(内部资料)
查看>>
自适应网页设计
查看>>
获取BT节点信息bittorrent-discovery
查看>>
Centos 7使用vsftpd搭建FTP服务器
查看>>
linux下SVN不允许空白日志提交
查看>>