CaptcahCode.java
package com.imooc.code;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
/**
* 验证码工具类
*/
public class CaptcahCode {
/**
* 验证码生成的方法
* @param response
* @return
*/
public static String drawImage(HttpServletResponse response) {
//1、定义以字符串的拼接的StringBuilder
StringBuilder builder = new StringBuilder();
//产生4个字符串的随机数
for (int i = 0; i < 4; i++) {
builder.append(randomChar());
}
String code = builder.toString();
//2、定义图片的宽度和高度
int width = 120;
int height = 25;
/**
*建立bufferedImage对象,制定图片的长度和宽度以及色彩,图片的缓冲流
* 把绘制的每个步骤先写入到缓冲流,然后进行输出,达到高效的目的,TYPE_3BYTE_BGR表示三原色
*/
BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR);
//3、获取到Graphic2D 绘制对象,开始绘制验证码
Graphics2D g = bi.createGraphics();
//4、设置文字的字体和大小
Font font = new Font("微软雅黑",Font.PLAIN,20);
//设置字体的颜色
Color color = new Color(0,0,0);
//关联字体属性
g.setFont(font);
//关联字体颜色
g.setColor(color);
//设置背景
g.setBackground(new Color(226, 235,240));
//开始绘制对象
g.clearRect(0,0,width,height);
//绘制形状,获取矩形对象
FontRenderContext context = g.getFontRenderContext();
Rectangle2D bounds = font.getStringBounds(code,context);
//计算文字的坐标和间距
double x = (width - bounds.getWidth())/2;
double y = (height - bounds.getHeight())/2;
double ascent = bounds.getY();
double baseY = y - ascent;
g.drawString(code,(int)x,(int)baseY);
//结束绘制
g.dispose();
try {
//这里可能会抛异常,加个try catch,把图片写到response
ImageIO.write(bi,"jpg",response.getOutputStream());
//刷新响应流
response.flushBuffer();
} catch (IOException e) {
e.printStackTrace();
};
//验证码的对比和存储
return code;
}
/**
* 此方法用于产生随机字母和数字组合
* @return
*/
private static char randomChar(){
//1、定义验证需要的字母和数字
String string = "QWERTYUIOPASDFGHJKLZXCVBNM1234567890";
//2、定义随机对象,随机从字符串长度中选择一个字符
Random random = new Random();
return string.charAt(random.nextInt(string.length()));
}
}
code.jsp
<%@ page import="com.imooc.code.CaptcahCode" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
//1、清空浏览器缓存,保证验证码图片来自服务器而不是本地缓存
response.setHeader("pragma","no-cache");
response.setHeader("cache-control","no-cache");
response.setHeader("expires","0");
//2、调用编写的生成验证码的工具
String code = CaptcahCode.drawImage(response);
session.setAttribute("code",code);
//我这里遇到一个问题,在firefox和ie没问题,用chrome就打不开,而且还报错ERR_INCOMPLETE_CHUNKED_ENCODING,然后执行下面的第三步操作,chrome就可以了...,
//3、解决getOutputStream异常问题,但是不知道为啥这么些
out.clear();
out = pageContext.pushBody();
%>
index.jsp
<%--
Created by IntelliJ IDEA.
User: msi
Date: 2020/7/4
Time: 8:47
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>验证码</title>
</head>
<body>
<img src="code.jsp" alt="oops" id = "code">
<a href="javascript:void(0);" onclick="changeCode()">换一张</a>
<script>
function changeCode() {
//这里加?time=是为了避免浏览器缓存而导致加载不出验证码
document.getElementById("code").src = "code.jsp"+"?time="+new Date().getTime();
}
</script>
</body>
</html>