在Web程序中,验证码是经常使用的技术之一。Web程序永远面临未知用户和未知程序的探测。为了防止恶意脚本的执行,验证码技术无疑是首选方案之一。本文将讨论如何在JSP和Servlet中使用验证码技术。
验证码的产生思路很简单,在Servlet中随机产生验证码字符序列,并计入session中,JSP中以图片的形式进行显示。当用户在JSP表单中输入验证码并提交时,在相应的Servlet中验证是否与session中保存的验证码一致。下面通过代码,一次演示验证码产生和实现的验证的过程。1.验证码的产生
我们需要创建一个名为ValcodeServlet的servlet并在其doGet()方法中完成验证码的产生。首先通过随机数的产生类Random随机产生一个4位的验证码,并将其存入session;然后使用BufferedImage和Graphics类把验证码转为图片,当然为了起到较好的效果,我们需要添加一些干扰线;最后使用ImageIO将图片输出。详细代码如下:
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
|
protectedvoiddoGet(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {
// 告知浏览当作图片处理
response.setContentType(
"image/jpeg"
);
// 告诉浏览器不缓存
response.setHeader(
"pragma"
,
"no-cache"
);
response.setHeader(
"cache-control"
,
"no-cache"
);
response.setHeader(
"expires"
,
"0"
);
// 产生由4位数字构成的验证码
int
length =
4
;
String valcode =
""
;
Random rd =
new
Random();
for
(
int
i=
0
; i<length; i++)
valcode+=rd.nextInt(
10
);
// 把产生的验证码存入到Session中
HttpSession session = request.getSession();
session.setAttribute(
"valcode"
, valcode);
// 产生图片
int
width =
80
;
int
height =
25
;
BufferedImageimg = newBufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
// 获取一个Graphics
Graphics g = img.getGraphics();
// 填充背景色
g.setColor(Color.WHITE);
g.fillRect(
0
,
0
, width, height);
// 填充干扰线50
for
(
int
i=
0
; i<
50
; i++){
g.setColor(
new
Color(rd.nextInt(
100
)+
155
,rd.nextInt(
100
)+
155
,rd.nextInt(
100
)+
155
));
g.drawLine(rd.nextInt(width), rd.nextInt(height),rd.nextInt(width), rd.nextInt(height));
}
// 绘制边框
g.setColor(Color.GRAY);
g.drawRect(
0
,
0
, width-
1
, height-
1
);
// 绘制验证码
Font[] fonts = {
new
Font(
"隶书"
,Font.BOLD,
18
),
new
Font(
"楷体"
,Font.BOLD,
18
),
new
Font(
"宋体"
,Font.BOLD,
18
),
new
Font(
"幼圆"
,Font.BOLD,
18
)};
for
(
int
i=
0
; i<length; i++){
g.setColor(
new
Color(rd.nextInt(
150
),rd.nextInt(
150
),rd.nextInt(
150
)));
g.setFont(fonts[rd.nextInt(fonts.length)]);
g.drawString(valcode.charAt(i)+
""
, width/valcode.length()*i+
2
,
18
);
}
// 输出图像
g.dispose();
ImageIO.write(img,
"jpeg"
, response.getOutputStream());
}
|
上面的代码只是产生了一个常规的验证码,我们可以根据自己的需要对验证码的产生策略和干扰线进行调整。Servlet编写完毕,别忘了在web.xml中进行配置以便能在JSP中调用,其代码如下:
1
2
3
4
5
6
7
8
9
|
<servlet>
<description></description>
<display-name>ValcodeServlet</display-name>
<servlet-name>ValcodeServlet</servlet-name><servlet-
class
>org.icer.jee.valcode.servlet.ValcodeServlet</servlet-
class
>
</servlet>
<servlet-mapping>
<servlet-name>ValcodeServlet</servlet-name>
<url-pattern>/ValcodeServlet</url-pattern>
</servlet-mapping>
|
产生验证码的servlet编写完毕,并且已经web.xml中进行了配置,那么我们在input.jsp中使用<img />标记以图片的方式调用servlet即可显示验证码。
当然为了能起到验证效果,本例中还包含了简单的表单。为了放置验证码无法识别,此处还提供了看不清点击换一张功能,用户点击图片时重新加载验证码图片(问号是为了放置浏览器缓存而不能实现重新请求图片)。JSP中表单部分代码如下:
1
2
3
4
5
|
<
formname
=
"form1"
method
=
"post"
action
=
"LoginServlet"
>
验证码:<
inputname
=
"vcode"
type
=
"text"
class
=
"input02"
id
=
"vcode"
>
<
imgsrc
=
"ValcodeServlet"
align
=
"absmiddle"
title
=
"看不清,点击换一张"
onClick
=
"this.src=this.src+'?'"
/>
<
inputtype
=
"submit"
name
=
"button"
id
=
"button"
value
=
"提交"
>
</
form
>
|
当表单提交到CheckServlet时,对用户填写的验证码和session中存储的验证码进行比对,根据结果给出不同提示。代码如下:
1
2
3
4
5
6
7
8
9
10
11
|
protectedvoiddoPost(HttpServletRequest request, HttpServletResponse response) throwsServletException, IOException {
// 获取验证码
String valcode = request.getSession().getAttribute(
"valcode"
).toString();
// 获取用户填写的验证码
String vcode = request.getParameter(
"vcode"
);
// 进行验证
if
(!valcode.equals(vcode))
System.out.println(
">>>验证码错误!"
);
else
System.out.println(
">>>验证码正确!"
);
}
|
总起来说,验证码技术本质上就是利用Java绘图技术把随机产生的验证码字符图形化,并在JSP中以图形调用,最后在用户提交表单后在对应的servlet中进行验证。本文只是提供验证码的基本实现思路,希望大家能灵活应用。