您的位置:首页 > 编程语言 > Java开发

java生成图形验证码

2017-11-09 14:54 435 查看
1.开发所需jar包

commons-codec-1.10.jar

commons-lang-2.5.jar

log4j-1.2.17.jar

2.图形验证码工具类代码

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.QuadCurve2D;
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.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CaptchaUtils {

private static final Logger LOG = LoggerFactory.getLogger(CaptchaUtils.class);
private static String captchaName = "captcha";
private static final CaptchaUtils INSTANCE = new CaptchaUtils();

// 默认的验证码大小
private static final int WIDTH = 100, HEIGHT = 46;
// 验证码随机字符数组
private static final String[] strArr = { "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H",
"J", "K", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y" };
// 验证码字体
private static final Font[] RANDOM_FONT = new Font[] {
new Font("nyala", Font.BOLD, 38),
new Font("Arial", Font.BOLD, 32),
new Font("Bell MT", Font.BOLD, 32),
new Font("Credit valley", Font.BOLD, 34),
new Font("Impact", Font.BOLD, 32),
new Font(Font.MONOSPACED, Font.BOLD, 40)
};

public static CaptchaUtils getInstance() {
return INSTANCE;
}

/**
* 生成验证码
*
* @throws IOException
*/
public void render(HttpServletResponse response) throws IOException,Exception {
BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
String vCode = drawGraphic(image);
vCode = vCode.toUpperCase(); // 转成大写重要
System.out.println(vCode);
vCode = DigestUtils.md5Hex(vCode);
Cookie cookie = new Cookie(captchaName, vCode);
cookie.setMaxAge(-1);
cookie.setPath("/");
try {
// try catch 用来兼容不支持 httpOnly 的 tomcat、jetty
cookie.setHttpOnly(true);
} catch (Exception e) {
LOG.error("", e);
}
response.addCookie(cookie);
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
response.setContentType("image/jpeg");

ServletOutputStream sos = null;
try {
sos = response.getOutputStream();
ImageIO.write(image, "jpeg", sos);
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw e;
} finally {
if (sos != null) {
try {
sos.close();
} catch (IOException e) {
LOG.error("", e);
}
}
}
}

private String drawGraphic(BufferedImage image) {
// 获取图形上下文
Graphics2D g = image.createGraphics();

g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
// 图形抗锯齿
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// 字体抗锯齿
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

// 设定背景色
g.setColor(getRandColor(200, 250));
g.fillRect(0, 0, WIDTH, HEIGHT);

// 生成随机类
Random random = new Random();
// 设定字体
g.setFont(RANDOM_FONT[random.nextInt(RANDOM_FONT.length)]);

// 画蛋蛋,有蛋的生活才精彩
Color color;
for (int i = 0; i < 10; i++) {
color = getRandColor(120, 200);
g.setColor(color);
g.drawOval(random.nextInt(WIDTH), random.nextInt(HEIGHT), 5 + random.nextInt(10), 5 + random.nextInt(10));
color = null;
}

// 取随机产生的认证码(4位数字)
String sRand = "";
for (int i = 0; i < 4; i++) {
String rand = String.valueOf(strArr[random.nextInt(strArr.length)]);
sRand += rand;
// 旋转度数 最好小于45度
int degree = random.nextInt(28);
if (i % 2 == 0) {
degree = degree * (-1);
}
// 定义坐标
int x = 22 * i, y = 21;
// 旋转区域
g.rotate(Math.toRadians(degree), x, y);
// 设定字体颜色
color = getRandColor(20, 130);
g.setColor(color);
// 将认证码显示到图象中
g.drawString(rand, x + 8, y + 10);
// 旋转之后,必须旋转回来
g.rotate(-Math.toRadians(degree), x, y);
color = null;
}
// 图片中间线
g.setColor(getRandColor(0, 60));
// width是线宽,float型
BasicStroke bs = new BasicStroke(3);
g.setStroke(bs);
// 画出曲线
QuadCurve2D.Double curve = new QuadCurve2D.Double(0d, random.nextInt(HEIGHT - 8) + 4, WIDTH / 2, HEIGHT / 2,
WIDTH, random.nextInt(HEIGHT - 8) + 4);
g.draw(curve);
// 销毁图像
g.dispose();
return sRand;
}

/*
* 给定范围获得随机颜色
*/
private Color getRandColor(int fc, int bc) {
Random random = new Random();
if (fc > 255) {
fc = 255;
}
if (bc > 255) {
bc = 255;
}
int r = fc + random.nextInt(bc - fc);
int g = fc + random.nextInt(bc - fc);
int b = fc + random.nextInt(bc - fc);
return new Color(r, g, b);
}

/**
* 仅能验证一次,验证后立即销毁 cookie
* @param controller 控制器
* @param userInputCaptcha 用户输入的验证码
* @return 验证通过返回 true, 否则返回 false
*/
public boolean validate(HttpServletRequest request, HttpServletResponse response, String userInputCaptcha) {
if (StringUtils.isEmpty(userInputCaptcha)) {
return false;
}

request.getCookies();

userInputCaptcha = userInputCaptcha.toUpperCase();  // 转成大写重要
userInputCaptcha = DigestUtils.md5Hex(userInputCaptcha);
boolean result = userInputCaptcha.equals(getCookie(request, captchaName));
if (result == true) {
removeCookie(response, captchaName);
}
return result;
}

private String getCookie(HttpServletRequest request, String name) {
Cookie[] cookies = request.getCookies();
String value = null;
for (Cookie cookie : cookies) {
if (cookie.getName().equals(name)) {
value = cookie.getValue();
break;
}
}
return value;
}

private void removeCookie(HttpServletResponse response, String name) {
Cookie cookie = new Cookie(captchaName, StringUtils.EMPTY);
cookie.setHttpOnly(true);
cookie.setMaxAge(0);            // 0:delete
cookie.setPath("/");
response.addCookie(cookie);
}
}


3.调用图形验证码

@RequestMapping(value="/captcha")
public void captcha(HttpServletRequest request, HttpServletResponse response) {
try {
CaptchaUtils.getInstance().render(response);
} catch(IOException e) {
LOGGER.error("", e);
} catch(Exception e) {
LOGGER.error("", e);
}
}


4.效果

大小:100*46

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 验证码