Implementing CAPTCHA Verification in Java with Servlet and HTML
This guide demonstrates how to create a CAPTCHA verification feature in Java by generating random characters and interference lines using Graphics, serving the image via a servlet, and integrating it into an HTML registration page with JavaScript for dynamic refresh.
CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) is widely used to protect account security. The following tutorial shows how to implement a CAPTCHA verification function in Java, generate the image with random letters and interference lines, and embed it in a web registration form.
First, a helper class GraphicHelper is created to draw random characters on a BufferedImage. The class provides a static create method that receives the image width, height, image type and an OutputStream, then returns the generated verification string.
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
import javax.imageio.ImageIO;
public final class GraphicHelper {
/**
* Generate a CAPTCHA image and return the verification string.
* @param width Image width
* @param height Image height
* @param imgType Image format (e.g., "jpeg")
* @param output Output stream for the image
* @return The generated verification code as a string
*/
public static String create(final int width, final int height, final String imgType, OutputStream output) {
StringBuffer sb = new StringBuffer();
Random random = new Random();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics graphic = image.getGraphics();
graphic.setColor(Color.getColor("F8F8F8"));
graphic.fillRect(0, 0, width, height);
Color[] colors = new Color[] { Color.BLUE, Color.GRAY, Color.GREEN, Color.RED, Color.BLACK, Color.ORANGE, Color.CYAN };
// Draw interference lines
for (int i = 0; i < 50; i++) {
graphic.setColor(colors[random.nextInt(colors.length)]);
int x = random.nextInt(width);
int y = random.nextInt(height);
int w = random.nextInt(20);
int h = random.nextInt(20);
int signA = random.nextBoolean() ? 1 : -1;
int signB = random.nextBoolean() ? 1 : -1;
graphic.drawLine(x, y, x + w * signA, y + h * signB);
}
// Draw characters
graphic.setFont(new Font("Comic Sans MS", Font.BOLD, 30));
for (int i = 0; i < 6; i++) {
int temp = random.nextInt(26) + 97;
String s = String.valueOf((char) temp);
sb.append(s);
graphic.setColor(colors[random.nextInt(colors.length)]);
graphic.drawString(s, i * (width / 6), height - (height / 3));
}
graphic.dispose();
try {
ImageIO.write(image, imgType, output);
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
}Next, a servlet VerifyCodeServlet is defined to handle requests for the CAPTCHA image. It creates the image using GraphicHelper.create, writes the image to the response output stream, and stores the generated code in the HTTP session keyed by the request URI.
import java.io.IOException;
import java.io.OutputStream;
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;
@WebServlet(urlPatterns = "/verify/regist.do")
public class VerifyCodeServlet extends HttpServlet {
private static final long serialVersionUID = 3398560501558431737L;
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
String uri = request.getRequestURI();
System.out.println("hello : " + uri);
final int width = 180; // image width
final int height = 40; // image height
final String imgType = "jpeg"; // image format
OutputStream output = response.getOutputStream();
String code = GraphicHelper.create(width, height, imgType, output);
System.out.println("验证码内容: " + code);
// Associate the generated code with the request URI in the session
session.setAttribute(uri, code);
System.out.println(session.getAttribute(uri));
}
}The generated CAPTCHA image is then used in an HTML registration page. The page contains input fields for username, password, password confirmation, and the verification code, as well as an <img> element that displays the CAPTCHA and refreshes when clicked.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>注册</title>
<link rel="stylesheet" href="styles/general.css">
<link rel="stylesheet" href="styles/cell.css">
<link rel="stylesheet" href="styles/form.css">
<script type="text/javascript" src="js/ref.js"></script>
<style type="text/css">
.logo-container { margin-top:50px; }
.logo-container img { width:100px; }
.message-container { height:80px; }
.link-container { height:40px; line-height:40px; }
.link-container a { text-decoration:none; }
</style>
</head>
<body>
<div class="container form-container">
<form action="/wendao/regist.do" method="post">
<!-- username -->
<div class="form-row">
<span class="cell-1"><i class="fa fa-user"></i></span>
<span class="cell-11" style="text-align:left;">
<input type="text" name="username" placeholder="请输入用户名">
</span>
</div>
<!-- password -->
<div class="form-row">
<span class="cell-1"><i class="fa fa-key"></i></span>
<span class="cell-11" style="text-align:left;">
<input type="password" name="password" placeholder="请输入密码">
</span>
</div>
<!-- confirm password -->
<div class="form-row">
<span class="cell-1"><i class="fa fa-keyboard-o"></i></span>
<span class="cell-11" style="text-align:left;">
<input type="password" name="confirm" placeholder="请确认密码">
</span>
</div>
<!-- verification code input and image -->
<div class="form-row">
<span class="cell-7">
<input type="text" name="verifyCode" placeholder="请输入验证码">
</span>
<span class="cell-5" style="text-align:center;">
<img src="/demo/verify/regist.do" onclick="myRefersh(this)">
</span>
</div>
<!-- submit / reset buttons -->
<div class="form-row" style="border:none;">
<span class="cell-6" style="text-align:left;">
<input type="reset" value="重置">
</span>
<span class="cell-6" style="text-align:right;">
<input type="submit" value="注册">
</span>
</div>
</form>
</div>
</body>
</html>To make the CAPTCHA image refresh without reloading the whole page, a small JavaScript function myRefersh is added. It extracts the current src of the image, appends (or replaces) a query parameter with the current timestamp, and assigns the new URL back to the image source, forcing the browser to request a new image.
function myRefersh(e) {
const source = e.src; // original src
var index = source.indexOf("?"); // find ?
if (index > -1) {
var s = source.substring(0, index);
var date = new Date();
var time = date.getTime();
e.src = s + "?time=" + time;
} else {
var date = new Date();
e.src = source + "?time=" + date.getTime();
}
}With these components, the CAPTCHA can be generated on the server side, displayed on the registration form, and refreshed instantly by clicking the image, providing a simple yet effective verification mechanism for Java web applications.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Captain
Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
