有两种方式,一种jsp方式,一种java方式(该方式自己改造的)
【采用jsp方式】
服务端生成代码:
<%@ page contentType="image/jpeg" import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" pageEncoding="gb2312"%> <% response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); try { //在内存中创建图象 int width = 60; //图像的宽度 int height = 20; //图像的高度 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); //获取图形上下文 Graphics g = image.getGraphics(); //设定背景色 g.setColor(new Color(0xDCDCDC)); g.fillRect(0, 0, width, height); //画边框 g.setColor(Color.black); g.drawRect(0, 0, width - 1, height - 1); //取随机产生的认证码(4位数字) Random random = new Random(); //生成0-9999的随机数 int randomNum = random.nextInt(9999); //将验证码存在session中 // session.setAttribute("rand",sRand); String randStr = String.valueOf(randomNum); switch (randStr.length()) { case 1: randStr = "000" + randStr; break; case 2: randStr = "00" + randStr; break; case 3: randStr = "0" + randStr; break; default: randStr = randStr.substring(0, 4); break; } request.getSession().setAttribute("rand", randStr); //将认证码显示到图象中 g.setColor(Color.black); g.setFont(new Font("Atlantic Inline", Font.PLAIN, 18)); String Str = randStr.substring(0, 1); g.drawString(Str, 8, 17); Str = randStr.substring(1, 2); g.drawString(Str, 20, 15); Str = randStr.substring(2, 3); g.drawString(Str, 35, 18); Str = randStr.substring(3, 4); g.drawString(Str, 45, 15); // 随机产生88个干扰点,使图象中的认证码不易被其它程序探测到 for (int i = 0; i < 20; i++) { int x = random.nextInt(width); int y = random.nextInt(height); g.drawOval(x, y, random.nextInt(5), random.nextInt(5)); } // 图象生效 g.dispose(); // 输出图象到页面 ImageIO.write(image, "JPEG", response.getOutputStream()); out.clear(); out = pageContext.pushBody(); } catch (Exception e) { e.printStackTrace(); out.println(e.toString()); } %>
<script> function show(o){ var timenow = new Date().getTime(); o.src="${base}/template2/common/image.jsp?d="+timenow; } </script> <span> <img src="${base}/template2/common/image.jsp" align="absmiddle" id="checkImage" onclick="show(document.getElementById('checkImage'))"/> </span> <a href="javascript:show(document.getElementById('checkImage'))"><span>看不清?换一张</span></a>
【采用java方式】
该方式有个弊端就是由于采用springmvc的responsebody注解无法有效设定response头清除缓存,所以多次调用同一个请求时候要在请求的url后面加随机数,如ur+”?data=“+new Date(),这样才能避免客户端不重复发同样请求到服务端的问题,搞IT的都懂这个方法,也知道什么原因,如有更好的解决办法请给予分享,谢谢
先创建一个Vcode类来作数据模型:
package com.wwwcoffee.base; import java.awt.image.BufferedImage; public class Vcode { private String code; private BufferedImage image; public String getCode() { return code; } public void setCode(String code) { this.code = code; } public BufferedImage getImage() { return image; } public void setImage(BufferedImage image) { this.image = image; } }再创建一个辅助工具类生成校验码模型:
package com.wwwcoffee.utils; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.util.Random; import javax.imageio.ImageIO; import com.wwwcoffee.base.Vcode; public class VcodeUtil { public static Vcode generate() throws Exception { // 在内存中创建图象 int width = 60; // 图像的宽度 int height = 20; // 图像的高度 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 获取图形上下文 Graphics g = image.getGraphics(); // 设定背景色 g.setColor(new Color(0xDCDCDC)); g.fillRect(0, 0, width, height); // 画边框 g.setColor(Color.black); g.drawRect(0, 0, width - 1, height - 1); // 取随机产生的认证码(4位数字) Random random = new Random(); // 生成0-9999的随机数 int randomNum = random.nextInt(9999); String randStr = String.valueOf(randomNum); switch (randStr.length()) { case 1: randStr = "000" + randStr; break; case 2: randStr = "00" + randStr; break; case 3: randStr = "0" + randStr; break; default: randStr = randStr.substring(0, 4); break; } // 将认证码显示到图象中 g.setColor(Color.black); g.setFont(new Font("Atlantic Inline", Font.PLAIN, 18)); String Str = randStr.substring(0, 1); g.drawString(Str, 8, 17); Str = randStr.substring(1, 2); g.drawString(Str, 20, 15); Str = randStr.substring(2, 3); g.drawString(Str, 35, 18); Str = randStr.substring(3, 4); g.drawString(Str, 45, 15); // 随机产生88个干扰点,使图象中的认证码不易被其它程序探测到 for (int i = 0; i < 20; i++) { int x = random.nextInt(width); int y = random.nextInt(height); g.drawOval(x, y, random.nextInt(5), random.nextInt(5)); } // 图象生效 g.dispose(); Vcode v = new Vcode(); v.setCode(randStr); v.setImage(image); return v; } }最后在controller类的方法中调用实现:
/** * 生成校验码 * @return */ @RequestMapping(value="getValidateCode") @ResponseBody public byte[] getValidateCode() { try { Vcode vcode = VcodeUtil.generate(); //生成校验码放入session中 this.getSession().setAttribute("vcodeserver", vcode.getCode()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write(vcode.getImage(), "JPEG", baos); return baos.toByteArray(); } catch (Exception e) { log.error(e.getMessage(), e); } return null; }