jfianl中的图形验证

来源:互联网 发布:问道手游刷道辅助软件 编辑:程序博客网 时间:2024/06/06 00:54

1.打开了一个页面,一般为登录界面,此时就已经访问了验证码接口captcha


2.自己写方法,调用jfianl的方法

/** * 验证码 */public void captcha() {CaptchaRender.setCaptchaName("my_captcha");renderCaptcha();}

3.jfinal

(1)setCaptchaName:设置验证码名称


private static String captchaName = "_jfinal_captcha";

/** * 设置 captchaName */public static void setCaptchaName(String captchaName) {if (StrKit.isBlank(captchaName)) {throw new IllegalArgumentException("captchaName can not be blank.");}CaptchaRender.captchaName = captchaName;}

(2)渲染renderCaptcha

private static final RenderFactory renderFactory = RenderFactory.me();

public void renderCaptcha() {render = renderFactory.getCaptchaRender();}

public Render getCaptchaRender() {return new CaptchaRender();}


CaptchaRender extends Render

CaptchaRender.class文件中有个默认的构造器

  public CaptchaRender() {    }


....此处省略一些jfianl的invoke代码,包括自己写的什么interceptor之类的......


3.走系统

ActionHandler

Render render = controller.getRender();

Controller

public Render getRender() {return render;}

render.setContext(request, response, action.getViewPath()).render();


进入抽象类Render

public Render setContext(HttpServletRequest request, HttpServletResponse response, String viewPath) {this.request = request;this.response = response;if (view != null && !view.startsWith("/"))view = viewPath + view;return this;}

4.开始画图了哈

里面有一个方法

/** * Render to client */public abstract void render();



CaptchaRender重写了这个方法

public void render() {BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);String vCode = drawGraphic(image);vCode = vCode.toUpperCase();// 转成大写重要vCode = HashKit.md5(vCode);Cookie cookie = new Cookie(captchaName, vCode);cookie.setMaxAge(-1);cookie.setPath("/");try {// try catch 用来兼容不支持 httpOnly 的 tomcat、jettycookie.setHttpOnly(true);} catch (Exception e) {LogKit.logNothing(e);}response.addCookie(cookie);response.setHeader("Pragma","no-cache");response.setHeader("Cache-Control","no-cache");response.setDateHeader("Expires", 0);response.setContentType("image/jpeg");ServletOutputStream sos = null;try {sos = response.getOutputStream();ImageIO.write(image, "jpeg", sos);} catch (IOException e) {if (getDevMode()) {throw new RenderException(e);}} catch (Exception e) {throw new RenderException(e);} finally {if (sos != null) {try {sos.close();} catch (IOException e) {LogKit.logNothing(e);}}}}private String drawGraphic(BufferedImage image){// 获取图形上下文Graphics2D g = image.createGraphics();g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);// 图形抗锯齿g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// 字体抗锯齿g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);// 设定背景色g.setColor(getRandColor(200, 250));g.fillRect(0, 0, WIDTH, HEIGHT);//生成随机类Random random = new Random();//设定字体g.setFont(RANDOM_FONT[random.nextInt(RANDOM_FONT.length)]);// 画蛋蛋,有蛋的生活才精彩Color color;for(int i = 0; i < 10; i++){color = getRandColor(120, 200);g.setColor(color);g.drawOval(random.nextInt(WIDTH), random.nextInt(HEIGHT), 5 + random.nextInt(10), 5 + random.nextInt(10));color = null;}// 取随机产生的认证码(4位数字)String sRand = "";for (int i = 0; i < 4; i++){String rand = String.valueOf(strArr[random.nextInt(strArr.length)]);sRand += rand;//旋转度数 最好小于45度int degree = random.nextInt(28);if (i % 2 == 0) {degree = degree * (-1);}//定义坐标int x = 22 * i, y = 21;//旋转区域g.rotate(Math.toRadians(degree), x, y);//设定字体颜色color = getRandColor(20, 130);g.setColor(color);//将认证码显示到图象中g.drawString(rand, x + 8, y + 10);//旋转之后,必须旋转回来g.rotate(-Math.toRadians(degree), x, y);color = null;}//图片中间线g.setColor(getRandColor(0, 60));//width是线宽,float型BasicStroke bs = new BasicStroke(3);g.setStroke(bs);//画出曲线QuadCurve2D.Double curve = new QuadCurve2D.Double(0d, random.nextInt(HEIGHT - 8) + 4, WIDTH / 2, HEIGHT / 2, WIDTH, random.nextInt(HEIGHT - 8) + 4);g.draw(curve);// 销毁图像g.dispose();return sRand;}/* * 给定范围获得随机颜色 */private 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);}/** * 仅能验证一次,验证后立即销毁 cookie * @param controller 控制器 * @param userInputCaptcha 用户输入的验证码 * @return 验证通过返回 true, 否则返回 false */public static boolean validate(Controller controller, String userInputCaptcha) {if (StrKit.isBlank(userInputCaptcha)) {return false;}userInputCaptcha = userInputCaptcha.toUpperCase();// 转成大写重要userInputCaptcha = HashKit.md5(userInputCaptcha);boolean result = userInputCaptcha.equals(controller.getCookie(captchaName));if (result == true) {controller.removeCookie(captchaName);}return result;}}