写在前面:
最近在项目中做了一个登录页面,用到了图片验证码的功能,所以记录一下。方便之后再有用到,直接拿来用即可。其实图片验证码的生成都是有固定步骤的,网上也有很多的例子,有的时候,如果不想深究,都是可以直接拿来用的。嘻嘻~~~~
生成图片验证码工具类并在struts2中使用,大概需要以下五个步骤:
1.获取随机数验证码字符串
2.生成验证码图片
3.将图片转为图片流格式
4.提供图片流类型的get()方法
5.配置struts.xml
其实上面的前三个步骤,都是在为生成图片验证码做准备,我们将前三步的内容,封装成一个图片验证码工具类。
图片验证码工具类:
/** * Description:生成图片验证码工具类 * 1.获取随机数验证码字符串 * 2.生成验证码图片 * 3.将图片转为图片流格式 * Author: Eleven * Date: 2017/12/16 8:35 */ public class CodeUtil { //1.生成随机数验证码字符串 public static String getCodeStr(){ //字符数组(除去易混淆的数字0、数字1、字母l、字母o、字母O) char[] codes = "23456789ABCDEFGHIJKMNPQRSTUVWXYZ".toCharArray(); //指定验证码长度 int len = 4; //生成随机的验证码字符串 String code = ""; for(int i=0;i<len;i++){ int r = (int) (Math.random()*codes.length); code += String.valueOf(codes[r]); } System.out.println("验证码字符串"+code); return code; } /** *生成验证码图片 * @param codeStr 验证码字符串 * @return 图片 */ public static BufferedImage createImage(String codeStr){ //验证码长度 int len = codeStr.length(); //字体大小 int fSize = 20; int fWidth = fSize + 1; //图片宽度 int width = fWidth * len + 6; //图片高度 int height = fSize * 2 + 1; //图片 BufferedImage img = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB ); //获取画笔 Graphics g = img.getGraphics(); //设置背景颜色 并填充 g.setColor(new Color(0xDCDCDC)); g.fillRect(0,0,width,height); //设置边框颜色 g.setColor(Color.LIGHT_GRAY); g.drawRect(0,0,width-1,height-1); //绘制小点点 1*1的小矩形 g.setColor(Color.LIGHT_GRAY); Random random = new Random(); for(int i=0;i<len*6;i++){ int x = random.nextInt(width); int y = random.nextInt(height); //1*1的小矩形 g.drawRect(x,y,1,1); } //或者填充100条干扰线 /* for (int i = 0; i < 100; i++) { g.setColor(getRandColor(160, 200)); g.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width), random.nextInt(height)); }*/ //绘制验证码 int codeY = height - 10; //g.setColor(new Color(19,148,246)); //设置字体 g.setFont(new Font(null, Font.BOLD, fSize)); for(int i=0;i<len;i++){ //设置随机颜色 g.setColor(new Color(random.nextInt(150), random.nextInt(150), random.nextInt(150))); g.drawString(String.valueOf(codeStr.charAt(i)),i * 17 + 9, codeY); } //关闭资源 g.dispose(); return img; } /** * 验证码图片转为流格式 * @param img 图片 * @return 图片流 */ public static ByteArrayInputStream getImgAsInputStream(BufferedImage img){ ByteArrayInputStream inputStream = null; ByteArrayOutputStream bos = new ByteArrayOutputStream(); JPEGImageEncoder jpeg = JPEGCodec.createJPEGEncoder(bos); try { jpeg.encode(img); byte[] bts = bos.toByteArray(); inputStream = new ByteArrayInputStream(bts); } catch (IOException e) { e.printStackTrace(); throw new BusinessException("图片转为图片流格式异常了呀"); } return inputStream; } //填充干扰线的时候生成随机颜色 public static 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); } }
工具类已经写好了(前三个步骤已经做完了),在action中进行调用(记得第四步的提供图片流的get()方法)
action类:
/** * Description:登录Action * Author: Eleven * Date: 2017/12/14 19:28 */ @Controller("LoginAction") public class LoginAction2 extends BaseAction{ //图片流 private ByteArrayInputStream inputStream; public String getCode(){ //利用验证码工具类生成图片验证码 //1.获取随机数验证码字符串 String code = CodeUtil.getCodeStr(); //2.生成验证码图片 BufferedImage image = CodeUtil.createImage(code); //3.将图片转为图片流格式 inputStream = CodeUtil.getImgAsInputStream(image); //获取验证码字符串存到session中 ActionContext.getContext().getSession().put("code", code); return SUCCESS; } //4.提供图片流的get()方法 public ByteArrayInputStream getInputStream() { return inputStream; } }
完成第5步,配置struts.xml文件:
<!--验证码-->
<action name="getCode" class="LoginAction" method="getCode">
<result type="stream">
<param name="contentType">image/jpeg</param>
<!--与action中提供get方法的变量名相同-->
<param name="inputName">inputStream</param>
</result>
</action>
经过上面的几个步骤,就已经大功告成了,下面我们在jsp页面进行调用:
<img id="codeImg" src="getCode" name="codeImg" height="25px" width="70px" alt="看不清,换一张" onclick="changeCode()">
src是调用获取验证码的action,可以点击图片进行更换验证码,调用的js如下:
<script type="text/javascript"> function changeCode(){ //加一个时间戳,防止浏览器不重新发送请求就直接使用缓存中的图片,而导致点击时不进行刷新 document.form1.codeImg.src = "${baseURL}/getCode.action?timeStamp=" + new Date().getTime(); } </script>
成功截图:
小小迷你图,啊哈哈哈~~~~~真可爱。。。。。。
参考链接:http://www.cnblogs.com/dongliyang/archive/2012/08/24/2654431.html