方式一:不用第三方jar生成验证码的方式
/** * 获取验证码 * @param width 长度 默认83 * @param height 高度 默认 30 * @param size 个数 默认 4(4个验证码对应长度为83;5-->103 ……) * @return */ public static BufferedImage createImageCode(Integer width,Integer height,Integer size) { width=(width==null||width<1)?83:width; height=(height==null||height<1)?30:height; size=(size==null||size<1)?4:size; BufferedImage image =null; try { image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics graphics = image.getGraphics(); Graphics2D g = (Graphics2D) graphics; g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setColor(new Color(241, 242, 243)); g.fillRect(0, 0, width, height); g.setFont(new Font("Arial", Font.ITALIC, 28)); g.drawLine(0, 0, 0, 0); String rand = ""; String sRand = "";//验证码明文 char[] ch = "abcde2345678gfynmnpwx".toCharArray();//不易混淆的验证码(推荐) // char[] ch = "ABCDEFGHIJKLNOPQRSTUVXYZ0123456789WM".toCharArray(); int d = 169; Random random = new Random(); for (int i = 0; i < size; i++) { if (size-1 == i) { rand = String.valueOf(ch[random.nextInt(ch.length - 2)]); } else { rand = String.valueOf(ch[random.nextInt(ch.length)]); } sRand += rand; g.setColor(new Color((d = random.nextInt(255) < 180 ? d : 234), random.nextInt(120), random.nextInt(120))); g.drawString(rand, 20 * i + 1, 25); } System.out.println("验证码=" + sRand); int ov = random.nextInt(32); for (int i = 0; i < (ov < 18 ? 18 : ov); i++) { g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255))); g.drawOval(random.nextInt(40) * 2, random.nextInt(14) * 2, 2, 2); } g.dispose(); return image; } catch (Exception e) { e.printStackTrace(); } return image; }
方式二:
用google的kaptcha 生成简单和个性化的验证码图片,下面是我弄的三个例子,基本第三个例子是工作上常用的;
官网地址:https://code.google.com/archive/p/kaptcha/downloads
导入jar:链接: https://pan.baidu.com/s/1gfwy3Az 密码: ma6g
package com.alipay.util; import com.google.code.kaptcha.Constants; import com.google.code.kaptcha.impl.DefaultKaptcha; import com.google.code.kaptcha.util.Config; import javax.imageio.ImageIO; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.Date; import java.util.Properties; /** * Created by ding on 2017-05-25. * 生成验证码 */ public class Code { private static long time = System.currentTimeMillis(); private static Properties properties = new Properties(); static { try { properties.load(Code.class.getClassLoader().getResourceAsStream("resources/constants.properties")); } catch (IOException e) { e.printStackTrace(); } } /** * 通过配置文件个性化配置验证码 */ public static void getCode() { //第一步 Config config = new Config(properties); DefaultKaptcha producer = new DefaultKaptcha();//创建与其上绘制的文字的验证码图像:默认是固定宽度是200.高度50 producer.setConfig(config); String content = producer.createText();//创建一个将写入扭曲的文本(这个用于保存到session中校验用户输入是否正确) System.out.println(content); BufferedImage image = producer.createImage(content);//创建一个将写入扭曲文本的图像。 String session_key = config.getSessionKey(); System.out.println("默认的session_key=" + session_key); String formatName = "png"; try { File file = new File("D:\project\imgs\" + time + "." + formatName); ImageIO.write(image, formatName, file); } catch (IOException e) { e.printStackTrace(); } } /** * 简单的配置一个验证码(生成图片) * * @param width //验证码图片长度 * @param height //验证码图片高度 * @param size //验证码个数 */ public static void getSimpleCode(String width, String height, String size) { Properties pp = new Properties(); pp.setProperty(Constants.KAPTCHA_IMAGE_HEIGHT, height); pp.setProperty(Constants.KAPTCHA_IMAGE_WIDTH, width); pp.setProperty(Constants.KAPTCHA_TEXTPRODUCER_FONT_SIZE, "");//验证码字体大小 pp.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, size); //第一步 Config config = new Config(pp); DefaultKaptcha producer = new DefaultKaptcha();//创建与其上绘制的文字的验证码图像:默认是固定宽度是200.高度50 producer.setConfig(config); String content = producer.createText();//创建一个将写入扭曲的文本(这个用于保存到session中校验用户输入是否正确) System.out.println(content); BufferedImage image = producer.createImage(content);//创建一个将写入扭曲文本的图像。 String formatName = "png"; try { File file = new File("D:\project\imgs\" + time + "." + formatName); ImageIO.write(image, formatName, file); } catch (IOException e) { e.printStackTrace(); } } /** * 一般是用作Controller的方法,直接接受一个什么请求 * 返回一个验证码图片流,响应到页面中 * * @param request * @param response */ // @RequestMapping(value="/getCodeImg.do") public void getCodeImage(HttpServletRequest request, HttpServletResponse response) { Properties pp = new Properties();//注意;用的时候提取到外面 String sessionKeyValue = "KAPTCHA_SESSION_KEY";//设置验证码的缓存名字 String sessionKeyDateValue = "KAPTCHA_SESSION_DATE";//设置验证码的缓存时间 pp.setProperty(Constants.KAPTCHA_SESSION_KEY, sessionKeyValue); pp.setProperty(Constants.KAPTCHA_SESSION_DATE, sessionKeyDateValue); String height = "50";//设置图片高度:尽量要>=50 String width = "200";//设置图片长度:尽量要>=200 String length = "4";//设置验证码个数: [4~6] pp.setProperty(Constants.KAPTCHA_IMAGE_HEIGHT, height); pp.setProperty(Constants.KAPTCHA_IMAGE_WIDTH, width); pp.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, length);//验证码个数 //第一步 Config config = new Config(pp); DefaultKaptcha producer = new DefaultKaptcha();//创建与其上绘制的文字的验证码图像:默认是固定宽度是200.高度50 producer.setConfig(config); String content = producer.createText();//创建一个将写入扭曲的文本(这个用于保存到session中校验用户输入是否正确) System.out.println("验证码=" + content); BufferedImage image = producer.createImage(content);//创建一个将写入扭曲文本的图像。 //把验证码设置到session中 request.getSession().setAttribute(sessionKeyValue, content); request.getSession().setAttribute(sessionKeyDateValue, new Date()); String session_key = config.getSessionKey(); System.out.println("KAPTCHA_session_key=" + session_key); String formatName = "png"; try {
//方式一: ServletOutputStream out = response.getOutputStream(); ImageIO.write(image, formatName, out);
//方式二:
//JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(response.getOutputStream());
//encoder.encode(image);
} catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { getCode(); getSimpleCode("200", "50", "5"); } }
下面是constants.properties文件:
KAPTCHA_SESSION_KEY = "KAPTCHA_SESSION_KEY"
KAPTCHA_SESSION_DATE = "KAPTCHA_SESSION_DATE"
####################### 常用配置 ###############################
#配置校验码是否出边界 默认 no
kaptcha.border =yes
#配置 边界(边框)颜色 默认 black(黑色)
kaptcha.border.color =red
#配置 背景色 从什么颜色转变什么颜色,如果不需要转变,from和to 都设置成一样的 默认 lightGray (浅灰)
kaptcha.background.clear.from =red
#配置 背景色 默认 white
kaptcha.background.clear.to =yellow
#配置图片宽度 默认200
kaptcha.image.width = 200
#配置图片高度 默认 50
kaptcha.image.height = 50
#配置 生成文本的长度(验证码的个数) 默认5, 注意:一旦设置了大于5,那么请增加对应图片的宽度
kaptcha.textproducer.char.length =4
#配置 生成文本的内容 默认 abcde2345678gfynmnpwx (去掉了易混淆的数字和字母)
kaptcha.textproducer.char.string =
#配置 边界(边框)厚度 默认 1
kaptcha.border.thickness =2
################################ 不常用配置 ###############################
#配置 噪声颜色 默认 black(黑色)
kaptcha.noise.color =lightGray
#配置 NoiseProducer的实现类 默认 DefaultNoise;
########## 注意:下面所有实现类配置都必需带包名 !!!
kaptcha.noise.impl =com.google.code.kaptcha.impl.DefaultNoise
#配置 遮蔽层 默认
kaptcha.obscurificator.impl =
#配置 默认
kaptcha.producer.impl =
#配置 生成文本的实现类 默认
kaptcha.textproducer.impl =
#配置 生成文本的字体 默认 Arial
kaptcha.textproducer.font.names =
#配置 文本的颜色(验证码的颜色) 默认 black(黑色)
kaptcha.textproducer.font.color =
#配置 文本的大小(验证码的大小) 默认 40
kaptcha.textproducer.font.size =
#配置 文本的空间 (验证码之间的间隙) 默认 2 (最小值>=1)
kaptcha.textproducer.char.space =10
#配置 字体渲染 默认 DefaultWordRenderer
kaptcha.word.impl =
#配置 背景实现类 默认 DefaultBackground
kaptcha.background.impl =
getCodeImage方法在JSp页面中的图片代码
<img src="xxx/getCodeImg.do" id="kaptchaImage" onclick="changeCode();"/><a href="#" onclick="changeCode()">看不清?换一张</a>
JS代码:
<script type="text/javascript">
function changeCode() { $('#kaptchaImage').hide().attr('src', './kaptcha/getKaptchaImage.do?' + Math.floor(Math.random()*100) ).fadeIn(); event.cancelBubble=true; } </script>