1 import java.util.Arrays; 2 /** 3 * 工具类,生成随机验证码字符串 4 * @version 1.0 2012/12/01 5 * @author shiyz 6 * 7 */ 8 public class SecurityCode { 9 /** 10 * 验证码难度级别,Simple只包含数字,Medium包含数字和小写英文,Hard包含数字和大小写英文 11 */ 12 public enum SecurityCodeLevel {Simple,Medium,Hard}; 13 14 /** 15 * 产生默认验证码,4位中等难度 16 * @return String 验证码 17 */ 18 public static String getSecurityCode(){ 19 return getSecurityCode(4,SecurityCodeLevel.Medium,false); 20 } 21 /** 22 * 产生长度和难度任意的验证码 23 * @param length 长度 24 * @param level 难度级别 25 * @param isCanRepeat 是否能够出现重复的字符,如果为true,则可能出现 5578这样包含两个5,如果为false,则不可能出现这种情况 26 * @return String 验证码 27 */ 28 public static String getSecurityCode(int length,SecurityCodeLevel level,boolean isCanRepeat){ 29 //随机抽取len个字符 30 int len=length; 31 32 //字符集合(除去易混淆的数字0、数字1、字母l、字母o、字母O) 33 char[] codes={'1','2','3','4','5','6','7','8','9', 34 'a','b','c','d','e','f','g','h','i','j','k','m','n','p','q','r','s','t','u','v','w','x','y','z', 35 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','P','Q','R','S','T','U','V','W','X','Y','Z'}; 36 37 //根据不同的难度截取字符数组 38 if(level==SecurityCodeLevel.Simple){ 39 codes=Arrays.copyOfRange(codes, 0,9); 40 }else if(level==SecurityCodeLevel.Medium){ 41 codes=Arrays.copyOfRange(codes, 0,33); 42 } 43 //字符集合长度 44 int n=codes.length; 45 46 //抛出运行时异常 47 if(len>n&&isCanRepeat==false){ 48 throw new RuntimeException( 49 String.format("调用SecurityCode.getSecurityCode(%1$s,%2$s,%3$s)出现异常,当isCanRepeat为%3$s时,传入参数%1$s不能大于%4$s", 50 len,level,isCanRepeat,n)); 51 } 52 //存放抽取出来的字符 53 char[] result=new char[len]; 54 //判断能否出现重复的字符 55 if(isCanRepeat){ 56 for(int i=0;i<result.length;i++){ 57 //索引 0 and n-1 58 int r=(int)(Math.random()*n); 59 60 //将result中的第i个元素设置为codes[r]存放的数值 61 result[i]=codes[r]; 62 } 63 }else{ 64 for(int i=0;i<result.length;i++){ 65 //索引 0 and n-1 66 int r=(int)(Math.random()*n); 67 68 //将result中的第i个元素设置为codes[r]存放的数值 69 result[i]=codes[r]; 70 71 //必须确保不会再次抽取到那个字符,因为所有抽取的字符必须不相同。 72 //因此,这里用数组中的最后一个字符改写codes[r],并将n减1 73 codes[r]=codes[n-1]; 74 n--; 75 } 76 } 77 return String.valueOf(result); 78 } 79 }
1 import java.awt.Color; 2 import java.awt.Font; 3 import java.awt.Graphics; 4 import java.awt.image.BufferedImage; 5 import java.io.ByteArrayInputStream; 6 import java.io.ByteArrayOutputStream; 7 import java.io.IOException; 8 import java.util.Random; 9 import com.sun.image.codec.jpeg.ImageFormatException; 10 import com.sun.image.codec.jpeg.JPEGCodec; 11 import com.sun.image.codec.jpeg.JPEGImageEncoder; 12 /** 13 * 验证码生成器类,可生成数字、大写、小写字母及三者混合类型的验证码。 14 * 支持自定义验证码字符数量; 15 * 支持自定义验证码图片的大小; 16 * 支持自定义需排除的特殊字符; 17 * 支持自定义干扰线的数量; 18 * 支持自定义验证码图文颜色 19 * @author shiyz 20 * @version 1.0 21 */ 22 public class SecurityImage { 23 /** 24 * 生成验证码图片 25 * @param securityCode 验证码字符 26 * @return BufferedImage 图片 27 */ 28 public static BufferedImage createImage(String securityCode){ 29 //验证码长度 30 int codeLength=securityCode.length(); 31 //字体大小 32 int fSize = 15; 33 int fWidth = fSize + 1; 34 //图片宽度 35 int width = codeLength * fWidth + 6 ; 36 //图片高度 37 int height = fSize * 2 + 1; 38 //图片 39 BufferedImage image=new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 40 Graphics g=image.createGraphics(); 41 //设置背景色 42 g.setColor(Color.WHITE); 43 //填充背景 44 g.fillRect(0, 0, width, height); 45 //设置边框颜色 46 g.setColor(Color.LIGHT_GRAY); 47 //边框字体样式 48 g.setFont(new Font("Arial", Font.BOLD, height - 2)); 49 //绘制边框 50 g.drawRect(0, 0, width - 1, height -1); 51 //绘制噪点 52 Random rand = new Random(); 53 //设置噪点颜色 54 g.setColor(Color.LIGHT_GRAY); 55 for(int i = 0;i < codeLength * 6;i++){ 56 int x = rand.nextInt(width); 57 int y = rand.nextInt(height); 58 //绘制1*1大小的矩形 59 g.drawRect(x, y, 1, 1); 60 } 61 //绘制验证码 62 int codeY = height - 10; 63 //设置字体颜色和样式 64 g.setColor(new Color(19,148,246)); 65 g.setFont(new Font("Georgia", Font.BOLD, fSize)); 66 for(int i = 0; i < codeLength;i++){ 67 g.drawString(String.valueOf(securityCode.charAt(i)), i * 16 + 5, codeY); 68 } 69 //关闭资源 70 g.dispose(); 71 return image; 72 } 73 /** 74 * 返回验证码图片的流格式 75 * @param securityCode 验证码 76 * @return ByteArrayInputStream 图片流 77 */ 78 public static ByteArrayInputStream getImageAsInputStream(String securityCode){ 79 BufferedImage image = createImage(securityCode); 80 return convertImageToStream(image); 81 } 82 /** 83 * 将BufferedImage转换成ByteArrayInputStream 84 * @param image 图片 85 * @return ByteArrayInputStream 流 86 */ 87 private static ByteArrayInputStream convertImageToStream(BufferedImage image){ 88 ByteArrayInputStream inputStream = null; 89 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 90 JPEGImageEncoder jpeg = JPEGCodec.createJPEGEncoder(bos); 91 try { 92 jpeg.encode(image); 93 byte[] bts = bos.toByteArray(); 94 inputStream = new ByteArrayInputStream(bts); 95 } catch (ImageFormatException e) { 96 e.printStackTrace(); 97 } catch (IOException e) { 98 e.printStackTrace(); 99 } 100 return inputStream; 101 } 102 }
1 private ByteArrayInputStream imageStream; 2 3 public String makePictureCode() throws Exception{ 4 //String securityCode = SecurityCode.getSecurityCode(4,SecurityCodeLevel.Hard, false).toLowerCase(); 5 6 //获取默认难度和长度的验证码 7 String securityCode = SecurityCode.getSecurityCode(); 8 imageStream = SecurityImage.getImageAsInputStream(securityCode); 9 //放入session中 10 ServletActionContext.getRequest().getSession().setAttribute("securityCode", securityCode); 11 return "success"; 12 13 } 14 public ByteArrayInputStream getImageStream() { 15 return imageStream; 16 } 17 18 19 public void setImageStream(ByteArrayInputStream imageStream) { 20 this.imageStream = imageStream; 21 }
struts2 xml配置:
1 <result name="success" type="stream"> 2 <param name="contentType">image/jpeg</param> 3 <param name="inputName">imageStream</param> 4 <param name="bufferSize">2048</param> 5 </result>
界面:
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 4 <html> 5 <head> 6 <title>IdentifyingCode page</title> 7 <script type="text/javascript"> 8 function myReload(){ 9 document.getElementById("createCheckCode").src=document.getElementById("createCheckCode").src + "?nocache="+new Date().getTime(); 10 } 11 </script> 12 </head> 13 14 <body>
效果:
这样一个验证码的功能就可以使用了...