[TOC]
介绍
图形验证码(Captcha)是一种用于区分用户是机器人还是人类的测试。它通常用于网站注册、评论等功能。Java Web开发中,我们可以使用Servlet来实现图形验证码的功能,下面就来介绍一下如何实现。
实现步骤
以下是Servlet实现图形验证码的完整步骤:
- 创建验证码图片
- 将验证码图片输出到页面
- 将验证码传入Session中
- 验证用户输入是否与Session中的验证码匹配
下面我们逐步来讲解。
创建验证码图片
先来看一下示例代码:
public class CaptchaServlet extends HttpServlet {
private int width = 100;//验证码图片的宽度
private int height = 40;//验证码图片的高度
private int codeCount = 4;//验证码字符个数
private int lineCount = 150;//干扰线个数
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = buffImg.createGraphics();
Random random = new Random();
// 设置背景色
g.setColor(Color.WHITE);
g.fillRect(0, 0, width, height);
// 设置字体
Font font = new Font("Fixedsys", Font.BOLD, 28);
g.setFont(font);
// 设置干扰线
for (int i = 0; i < lineCount; i++) {
int xs = random.nextInt(width);
int ys = random.nextInt(height);
int xe = xs + random.nextInt(width / 8);
int ye = ys + random.nextInt(height / 8);
g.setColor(getRandomColor());
g.drawLine(xs, ys, xe, ye);
}
// 设置验证码
String code = "";
for (int i = 0; i < codeCount; i++) {
String str = String.valueOf(random.nextInt(10));
code += str;
g.setColor(getRandomColor());
g.drawString(str, 25 * i + 10, 30);
}
// 释放图形资源
g.dispose();
// 将验证码保存在session中
HttpSession session = request.getSession();
session.setAttribute("code", code);
response.setContentType("image/jpeg");// 设置响应的类型格式为图片格式
OutputStream os = response.getOutputStream();// 得到向客户端输出图片的流
ImageIO.write(buffImg, "jpeg", os);// 输出图片流
os.close();
}
private Color getRandomColor() {
Random random = new Random();
return new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
}
}
CaptchaServlet
是我们创建的Servlet,其中doGet
方法用于处理GET请求,它会创建一个BufferedImage
对象,并在该对象上绘制验证码图片。在实现绘制验证码的代码中,我们首先设置了背景色为白色,并填充整个图片;然后设置字体为Fixedsys,字号为28;接着绘制干扰线[1],最后在图片上绘制随机生成的验证码,把它保存到session中。
将验证码图片输出到页面
在前面的示例中,我们已经将生成的验证码保存到了Session中。此时我们需要将验证码图片输出到页面,让用户能够看到它。
在HTML页面中,添加一个类似于下面的img标签:
<img src="CaptchaServlet" onclick="this.src='CaptchaServlet?'+new Date().getTime()">
当用户首次访问该页面时,CaptchaServlet
会生成验证码图片并输出到页面上。当用户点击该图片时,this.src
会发生变化,具体来说,它会在原来的URL后面加上一个时间戳,这样浏览器就会认为这是一个新的URL,重新请求该URL,CaptchaServlet
就会生成新的验证码图片并输出到页面上。
将验证码传入Session中
在生成验证码图片的时候,我们已经将验证码保存到Session中了。在该Session中,我们可以使用getAttribute
方法来获取保存的验证码。
验证用户输入是否与Session中的验证码匹配
当用户提交页面表单时,我们需要验证用户输入的验证码是否与Session中保存的验证码匹配。具体来说,我们可以使用类似于下面的代码进行比较:
String code = (String) session.getAttribute("code");
if (code.equals(userInputCode)) {
// 验证码正确
} else {
// 验证码错误
}
示例
下面是两个代码示例,分别实现了使用Servlet生成图形验证码和验证用户输入。
示例一:生成图形验证码
以下是实现生成图形验证码的代码示例:
<!-- captcha.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>验证码示例</title>
</head>
<body>
<form>
<label>验证码:</label>
<img src="CaptchaServlet" onclick="this.src='CaptchaServlet?'+new Date().getTime()">
<br>
<label>验证码输入:</label>
<input type="text" name="captcha">
<br>
<button type="submit">提交</button>
</form>
</body>
</html>
// CaptchaServlet.java
@WebServlet("/CaptchaServlet")
public class CaptchaServlet extends HttpServlet {
private int width = 100;//验证码图片的宽度
private int height = 40;//验证码图片的高度
private int codeCount = 4;//验证码字符个数
private int lineCount = 150;//干扰线个数
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = buffImg.createGraphics();
Random random = new Random();
// 设置背景色
g.setColor(Color.WHITE);
g.fillRect(0, 0, width, height);
// 设置字体
Font font = new Font("Fixedsys", Font.BOLD, 28);
g.setFont(font);
// 设置干扰线
for (int i = 0; i < lineCount; i++) {
int xs = random.nextInt(width);
int ys = random.nextInt(height);
int xe = xs + random.nextInt(width / 8);
int ye = ys + random.nextInt(height / 8);
g.setColor(getRandomColor());
g.drawLine(xs, ys, xe, ye);
}
// 设置验证码
String code = "";
for (int i = 0; i < codeCount; i++) {
String str = String.valueOf(random.nextInt(10));
code += str;
g.setColor(getRandomColor());
g.drawString(str, 25 * i + 10, 30);
}
// 释放图形资源
g.dispose();
// 将验证码保存在session中
HttpSession session = request.getSession();
session.setAttribute("code", code);
response.setContentType("image/jpeg");// 设置响应的类型格式为图片格式
OutputStream os = response.getOutputStream();// 得到向客户端输出图片的流
ImageIO.write(buffImg, "jpeg", os);// 输出图片流
os.close();
}
private Color getRandomColor() {
Random random = new Random();
return new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
}
}
在该示例中,当用户访问captcha.html时,该页面会自动请求CaptchaServlet,从而生成验证码图片并显示在该页面上。
示例二:验证用户输入
以下是实现验证用户输入的代码示例:
<!-- validate.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>验证码示例</title>
</head>
<body>
<form action="ValidateServlet" method="post">
<label>验证码:</label>
<img src="CaptchaServlet" onclick="this.src='CaptchaServlet?'+new Date().getTime()">
<br>
<label>验证码输入:</label>
<input type="text" name="captcha">
<br>
<button type="submit">提交</button>
</form>
</body>
</html>
// ValidateServlet.java
@WebServlet("/ValidateServlet")
public class ValidateServlet extends HttpServlet{
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
HttpSession session = request.getSession();
String serverCode = (String) session.getAttribute("code");
String userInputCode = request.getParameter("captcha");
if (serverCode.equals(userInputCode)) {
out.println("验证码输入正确!");
} else {
out.println("验证码输入错误!请重新输入!");
}
out.flush();
out.close();
}
}
在该示例中,当用户提交表单时,请求会发送到ValidateServlet,该Servlet需要从Session中获取生成的验证码,然后将用户输入的验证码与Session中的验证码进行比较,最后返回比较结果。
结论
本文介绍了使用Java Servlet实现图形验证码功能的完整攻略。当用户在浏览器中看到需要输入验证码时,通常需要访问Servlet生成验证码图片,将图片展示在页面上,等待用户输入。当用户提交表单后,需要将用户输入的验证码从表单中提交到Servlet中,在Servlet中可以将表单数据与Session中保存的验证码进行比较以验证验证码是否输入正确。这样就可以达到防止机器人攻击的目的。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java web开发之servlet图形验证码功能的实现 - Python技术站