java生成验证码图片

参考了些网上代码,自己写了一个验证


第一:写一个图片生成类

package com.demo.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* 生成一个校验图片
*/
public class ImageUtil {
private static final int WIDTH = 80;
private static final int HIGHT = 30;
private static final char[] CODE_SEQUENCE = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
// 验证码字符个数
private static final int CODE_COUNT = 4;
// 字体的位置参数
private static final int FONT_AREA = WIDTH / (CODE_COUNT + 1);

public static void createCheckImg(HttpServletRequest request,
HttpServletResponse response) throws IOException {
// 定义图像
BufferedImage bi = new BufferedImage(WIDTH, HIGHT,
BufferedImage.TYPE_INT_RGB);
Graphics2D gd = bi.createGraphics();
// 随机数
Random random = new Random();
// 矩形填充为白色
gd.fillRect(0, 0, WIDTH, HIGHT);
gd.setColor(Color.white);
// 根据高宽设置字体
// 字体四种风格 plain bold italic
Font font = new Font("Fixedsys", Font.BOLD, HIGHT - 5);
gd.setFont(font);
// 画边框
gd.setColor(Color.BLACK);
gd.drawRect(0, 0, WIDTH - 1, HIGHT - 1);
gd.setColor(Color.BLACK);
// 随机产生几条干扰线
for (int i = 0; i < 6; i++) {
int x1 = random.nextInt(WIDTH);
int y1 = random.nextInt(HIGHT);
int x2 = random.nextInt(20);
int y2 = random.nextInt(10);
gd.drawLine(x1, y1, x1 + x2, y1 + y2);
}
// 产生随机码
int red = 0, green = 0, blue = 0;
// 存储数据的buffer
StringBuffer sb = new StringBuffer();
for (int i = 0; i < CODE_COUNT; i++) {
// 得到随机数
String strRand = String.valueOf(CODE_SEQUENCE[random.nextInt(36)]);
// 产生随机的颜色
red = random.nextInt(255);
green = random.nextInt(255);
blue = random.nextInt(255);
// 将验证码绘成图案
gd.setColor(new Color(red, green, blue));
gd.drawString(strRand, (i ) * FONT_AREA, HIGHT - 4);// x,y表坐标位置,按照宽度分5个坐标
// 拼接数字
sb.append(strRand);
}
// 设置session
request.getSession().setAttribute("checkCode", sb.toString());
// 禁止图像缓存。
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
response.setContentType("image/jpeg");
ServletOutputStream sos = response.getOutputStream();
ImageIO.write(bi, "jpg", sos);
sos.close();
}
}

第二:
前端获取验证码
 <img src="${ctx}/uploadFile/createImg" id="checkImg" alt="wait..."/>
<a href="#" onclick="changeImg()">换一张</a>
<script type="text/javascript">
//换验证图片
function changeImg(){
var img = $("#checkImg");
var imgSrc = img.attr("src");
img.attr("src",changeUrl(imgSrc));
}

//无了使图片不一样,不让浏览器加上缓存,所以用时间戳来作为参数
function changeUrl(imgSrc){
var timestamp = (new Date()).valueOf();
var indexTemp =imgSrc.indexOf("=");
if(indexTemp>0){
var subUrl = imgSrc.substring(0,indexTemp);
var resultUrl = subUrl + "=" + timestamp;
return resultUrl;
}else{
var resultUrl = imgSrc + "?" + "timestamp=" + "timestamp";
return resultUrl;
}
}
</script>
### 如何使用Java生成验证码图片以用于登录功能的解决方案或代码示例 在Java中实现验证码图片生成并将其应用于登录功能,可以通过创建一个Servlet来完成。以下是一个完整的解决方案,包括验证码图片生成和验证过程。 #### 1. 验证码生成逻辑 验证码生成的核心是随机生成字符,并将这些字符绘制到图片上。以下是生成验证码图片的代码示例: ```java import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; public class VerifyCode { private static final int WIDTH = 100; // 图片宽度 private static final int HEIGHT = 50; // 图片高度 private String text; // 验证码文本 public BufferedImage getImage() { BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); Graphics2D g = (Graphics2D) image.getGraphics(); g.setColor(Color.WHITE); // 设置背景颜色 g.fillRect(0, 0, WIDTH, HEIGHT); g.setFont(new Font("Arial", Font.BOLD, 24)); // 设置字体 g.setColor(Color.BLACK); // 设置字体颜色 String code = generateText(); // 生成验证码字符串 this.text = code; // 将验证码绘制到图片上 for (int i = 0; i < code.length(); i++) { g.drawString(code.substring(i, i + 1), 20 * i + 10, 30); } // 添加干扰线 for (int i = 0; i < 5; i++) { g.setColor(getRandomColor()); g.drawLine(getRandomNumber(WIDTH), getRandomNumber(HEIGHT), getRandomNumber(WIDTH), getRandomNumber(HEIGHT)); } g.dispose(); return image; } public String getText() { return text; } private String generateText() { String base = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; StringBuilder sb = new StringBuilder(); for (int i = 0; i < 6; i++) { // 验证码长度为6 int number = (int) (Math.random() * base.length()); sb.append(base.charAt(number)); } return sb.toString(); } private Color getRandomColor() { int r = (int) (Math.random() * 255); int g = (int) (Math.random() * 255); int b = (int) (Math.random() * 255); return new Color(r, g, b); } private int getRandomNumber(int bound) { return (int) (Math.random() * bound); } public void output(BufferedImage image, File file) throws IOException { ImageIO.write(image, "jpg", file); } } ``` #### 2. Servlet 实现验证码生成 通过Servlet可以将生成验证码图片输出到浏览器端,供用户查看。以下是Servlet的实现代码: ```java import java.awt.image.BufferedImage; import java.io.IOException; 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.io.OutputStream; @WebServlet("/verifyCode") public class VerifyCodeServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { VerifyCode verifyCode = new VerifyCode(); BufferedImage image = verifyCode.getImage(); String code = verifyCode.getText(); HttpSession session = request.getSession(); session.setAttribute("verifyCode", code); // 将验证码存储到Session中 response.setContentType("image/jpeg"); response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); try (OutputStream os = response.getOutputStream()) { ImageIO.write(image, "jpg", os); } } } ``` #### 3. 登录功能中的验证码验证 在用户登录时,需要将用户输入的验证码与Session中存储的验证码进行比较。以下是登录验证的代码示例: ```java @WebServlet("/login") public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(); String inputCode = request.getParameter("verifyCode"); // 获取用户输入的验证码 String sessionCode = (String) session.getAttribute("verifyCode"); // 获取Session中的验证码 if (sessionCode != null && sessionCode.equalsIgnoreCase(inputCode)) { response.getWriter().println("登录成功!"); } else { response.getWriter().println("验证码错误,请重新输入!"); } } } ``` ### 注意事项 - 验证码图片生成后应立即存储到Session中,确保其唯一性和时效性[^1]。 - 在实际应用中,建议对验证码的有效期进行限制,例如设置为5分钟超时[^3]。 - 可以通过增加干扰线、噪点等手段提高验证码的安全性[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值