下面我来详细讲解“jsp+Servlet编程实现验证码的方法”的完整攻略。
什么是验证码?
验证码(CAPTCHA)是指计算机应用程序为区分用户是真实用户还是计算机程序而推出的一种测试。常见的验证码类型包括数字、字母、滑块等形式,用户需要正确地填写系统生成的图形码信息才能进行下一步操作。
实现验证码的原理
验证码的实现原理是利用了Web开发中的Session机制。当我们访问网站时,会话的ID会被存储在Web服务器端的存储器里。生成的验证码会放在一个Session中存储,并且在前端展示给用户。 用户提交表单时,后台会收到表单提交的数据及验证码,后台程序会从Session中取出验证码并与用户传输的验证码进行比较。如果输入的验证码不正确,后台程序可以拒绝接受表单数据。
实现步骤
在jsp页面中创建验证码的表单,并在后台通过Servlet生成验证码并存储到session中;通过判断session的值与用户输入的值是否一致,来实现验证码的验证。
具体的实现步骤:
- 创建验证码图片
首先,我们需要生成一副随机的验证码图片,可以使用Java的Graphics类,在图片上写入验证码字符串,并增加一些干扰线和干扰点,以使验证码更加难以被识别。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int width = 120;//定义图片宽度
int height = 30;//定义图片高度
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);//创建BufferedImage对象
Graphics g = image.getGraphics();//创建Graphics对象
//填充背景
g.setColor(Color.WHITE);
g.fillRect(0, 0, width, height);
//产生4个随机字符
String text = "";
String base = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
Random random = new Random();
for (int i = 0; i < 4; i++) {
//随机颜色
g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
//设置字体
Font font = new Font("宋体", Font.BOLD, 25);
g.setFont(font);
//画字符
char ch = base.charAt(random.nextInt(base.length()));
g.drawString("" + ch, (20 * i) + 12, 24);
text = text + ch;
}
//干扰线
for (int i = 0; i < 5; i++) {
g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
g.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width), random.nextInt(height));
}
//干扰点
for (int i = 0; i < 30; i++) {
g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
g.drawOval(random.nextInt(width), random.nextInt(height), 1, 1);
}
//将验证码存入Session
request.getSession().setAttribute("checkcode", text);
//response
response.setContentType("image/jpeg");
OutputStream os = response.getOutputStream();
ImageIO.write(image, "jpeg", os);
}
- 在jsp页面中使用img标签显示验证码图片
<%@page contentType="text/html;charset=UTF-8" language="java"%>
<html>
<head>
<meta charset="UTF-8">
<title>验证码示例</title>
</head>
<body>
<form action="RegisterServlet" method="post">
<label>用户名:</label>
<input name="username"><br>
<label>密码:</label>
<input name="password" type="password"><br>
<label>验证码:</label>
<input name="checkcode">
<img src="CheckCodeServlet" alt="验证码" onclick="this.src='CheckCodeServlet?d='+new Date().getTime()"><br>
<input type="submit" value="注册">
</form>
</body>
</html>
其中,img标签的src属性指向CheckCodeServlet的地址,onclick事件用来更新验证码图片。
- 在Servlet中获取并验证用户输入的验证码
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取输入的用户名、密码和验证码
String username = request.getParameter("username");
String password = request.getParameter("password");
String checkcode = request.getParameter("checkcode");
//从Session中获取验证码
String code = (String) request.getSession().getAttribute("checkcode");
//比较验证码
if(code.equalsIgnoreCase(checkcode)){
//验证码正确,进行注册操作
//...
}else {
//验证码错误,返回错误提示
response.getWriter().write("验证码错误!");
}
}
- 防止验证码过期
由于Session的默认过期时间比较短,验证码可能会在过期时间内失效,从而导致验证码验证失败。可以通过在Servlet中设置Session的有效时间来解决这个问题:
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//在初始化时获取配置的过期时间
String timeout = filterConfig.getInitParameter("timeout");
//将timeout转换为long类型
sessionTimeout = Long.parseLong(timeout);
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//获取Session
HttpSession session = request.getSession();
//设置Session的过期时间为30分钟
session.setMaxInactiveInterval((int)sessionTimeout);
filterChain.doFilter(request,response);
return;
}
示例说明
以下是两条完整的示例说明。
示例一:验证码登陆
如果我们要实现用户登录的时候需要输入验证码,可以在登录表单中加入验证码的输入框,并在后端进行验证码的验证。
登陆表单样式:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<center>
<h2>Welcome</h2>
<form method="post" action="loginServlet">
<table>
<tr>
<td>UserName:</td>
<td><input type="text" name="username"/></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="password"/></td>
</tr>
<tr>
<td>Code:</td>
<td><input type="text" name="checkcode"/><img src="CodeServlet" onclick="this.src='CodeServlet?'+new Date().getTime();"/></td>
</tr>
<tr>
<td colspan="2" align="right"><input type="submit" value="Login"/></td>
</tr>
</table>
</form>
</center>
</body>
</html>
CodeServlet代码:
package com.myblog.servlet;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
/**
* Created by gjy on 2021/7/6
**/
@WebServlet(name = "CodeServlet", urlPatterns = "/CodeServlet")
public class CodeServlet extends HttpServlet {
private static final long serialVersionUID = 2432440348832509368L;
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
int width = 120;
int height = 25;
// 创建BufferedImage对象,设置大小和参数设置
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
// 创建一个随机数生成器
int codeCount = 4;// 验证码长度为4
char code[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".toCharArray();
// 创建一个字符串,用于存储生成的验证码
StringBuffer buffer = new StringBuffer();
// 将验证码绘制到图像中
// randomCode用于保存随机产生的验证码,以便用户登录后进行验证
String randomCode = null;
for (int i = 0; i < codeCount; i++) {
// 得到随机产生的验证码数字
String strRand = String.valueOf(code[new Random().nextInt(code.length)]);
// 用随机产生的颜色将验证码绘制到图像中
g2d.setColor(new Color(new Random().nextInt(255),
new Random().nextInt(255), new Random().nextInt(255)));
g2d.drawString(strRand, 18 * i + 10, 19);
buffer.append(strRand);
}
// 将生成的验证码保存到session中,跟用户的输入进行比较
HttpSession session = request.getSession();
session.setAttribute("checkcode", buffer.toString());
g2d.dispose();
response.setContentType("image/jpeg");
OutputStream outputStream = response.getOutputStream();
// 输出图像到页面
ImageIO.write(image, "jpeg", outputStream);
outputStream.close();
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
loginServlet代码:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
String checkcode = request.getParameter("checkcode");
HttpSession session = request.getSession();
String trueCode = session.getAttribute("checkcode").toString();
if (checkcode == null || !trueCode.equals(checkcode)) {// 判断验证码是否输入正确
response.sendRedirect("check.html");
return;
}
System.out.println("The userName is " + username);
System.out.println("The password is " + password);
response.sendRedirect("login.jsp");
}
示例二:实现验证码注册
在使用表单进行用户注册时,我们也可以添加验证码输入框,以便验证。
注册页面样式:
<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Register</title>
</head>
<body>
<h2>Register</h2>
<form action="RegisterServlet" method="post">
<table>
<tr>
<td><label for="username">Username:</label></td>
<td><input type="text" id="username" name="username" required></td>
</tr>
<tr>
<td><label for="password">Password:</label></td>
<td><input type="password" id="password" name="password" required></td>
</tr>
<tr>
<td><label for="checkcode">Verification Code:</label></td>
<td>
<input type="text" id="checkcode" name="checkcode" required>
<img src="CodeServlet" onclick="this.src='CodeServlet?' + new Date().getTime();"/>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="Register">
</td>
</tr>
</table>
</form>
</body>
</html>
CodeServlet代码和上面示例一相同,就不再给出。
RegisterServlet代码:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
String checkcode = request.getParameter("checkcode");
HttpSession session = request.getSession();
String trueCode = session.getAttribute("checkcode").toString();
if (checkcode == null || !trueCode.equals(checkcode)) {// 判断验证码是否输入正确
response.getWriter().append("Incorrect Verification Code!");
return;
}
System.out.println("The userName is " + username);
System.out.println("The password is " + password);
response.getWriter().append("Register Success!");
}
总结
至此,“jsp+Servlet编程实现验证码的方法”已经说完了。通过本文,我们了解了验证码的作用与实现原理,并详细讲解了如何通过JSP和Servlet技术实现验证码。对于Web开发中需要验证用户身份的场景,使用验证码是保证安全性的一种常用方法。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:jsp+Servlet编程实现验证码的方法 - Python技术站