package com.ketayao.fensy.webutil; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Random; import javax.imageio.ImageIO; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import com.ketayao.fensy.cache.CacheManager; import com.ketayao.fensy.mvc.WebContext; import com.ketayao.fensy.util.RandomStringUtils; import com.ketayao.fensy.util.StringUtils; /** * //调用方法 * if(!ImageCaptchaService.validate(ctx.request())) * //提示错误信息 * 图形验证码 */ public class ImageCaptchaService { private final static String CACHE_REGION = "session"; private final static String COOKIE_NAME = "_reg_key_"; private static int WIDTH = 120; private static int HEIGHT = 40; private static int LENGTH = 5; private final static Random random = new Random(); /** * 生成验证码 * @param req * @param res * @throws IOException */ public static void get(WebContext ctx) throws IOException { if (ctx.isRobot()) { ctx.forbidden(); return; } ctx.closeCache(); ctx.getResponse().setContentType("image/png"); _render(_generateRegKey(ctx), ctx.getResponse().getOutputStream(), WIDTH, HEIGHT); } /** * 检查验证码是否正确 * @param req * @return */ public static boolean validate(HttpServletRequest req) { Cookie cke = RequestUtils.getCookie(req, COOKIE_NAME); if (cke == null) { String ssnId = req.getSession().getId(); String code1 = CacheManager.get(String.class, CACHE_REGION, ssnId); String code2 = req.getParameter("verifyCode"); return StringUtils.endsWithIgnoreCase(code1, code2); } if (cke != null && StringUtils.isNotBlank(cke.getValue())) { String key = cke.getValue(); String code1 = CacheManager.get(String.class, CACHE_REGION, key); String code2 = req.getParameter("verifyCode"); return StringUtils.endsWithIgnoreCase(code1, code2); } return false; } private static String _generateRegKey(WebContext ctx) { Cookie cke = ctx.getCookie(COOKIE_NAME); String REG_VALUE = null; if (cke == null || StringUtils.isBlank(cke.getValue())) { REG_VALUE = RandomStringUtils.randomAlphanumeric(20); ctx.setCookie(COOKIE_NAME, REG_VALUE, 3600, true); } else REG_VALUE = cke.getValue(); String code = RandomStringUtils.randomAlphanumeric(LENGTH).toUpperCase(); code.replace('0', 'W'); code.replace('o', 'R'); code.replace('I', 'E'); code.replace('1', 'T'); CacheManager.put(CACHE_REGION, REG_VALUE, code); if (ctx.getSession() != null) { CacheManager.put(CACHE_REGION, ctx.getSession().getId(), code); } return code; } /** * 画随机码图 * @param text * @param out * @param width * @param height * @throws IOException */ private static void _render(String text, OutputStream out, int width, int height) throws IOException { BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = (Graphics2D) bi.getGraphics(); g.setColor(Color.WHITE); g.fillRect(0, 0, width, height); //g.setColor(Color.RED); //g.drawRect(1,1,width-2,height-2); for (int i = 0; i < 10; i++) { g.setColor(_getRandColor(150, 250)); g.drawOval(random.nextInt(110), random.nextInt(24), 5 + random.nextInt(10), 5 + random.nextInt(10)); } Font mFont = new Font("Arial", Font.ITALIC, 28); g.setFont(mFont); g.setColor(_getRandColor(10, 240)); g.drawString(text, 10, 30); ImageIO.write(bi, "png", out); } private static Color _getRandColor(int fc, int bc) {//给定范围获得随机颜色 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); } public static void main(String[] args) throws IOException { String code = RandomStringUtils.randomAlphanumeric(LENGTH).toUpperCase(); code = code.replace('0', 'W'); code = code.replace('o', 'R'); code = code.replace('I', 'E'); code = code.replace('1', 'T'); FileOutputStream out = new FileOutputStream("d:\\aa.jpg"); _render(code, out, 120, 40); } }