All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jfinal.captcha.CaptchaRender Maven / Gradle / Ivy

Go to download

JFinal is a simple, light, rapid,independent, extensible Java WEB + ORM framework. The feature of JFinal looks like ruby on rails especially ActiveRecord.

There is a newer version: 5.2.3
Show newest version
/**
 * Copyright (c) 2011-2021, James Zhan 詹波 ([email protected]).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.jfinal.captcha;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.QuadCurve2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import com.jfinal.core.Controller;
import com.jfinal.kit.LogKit;
import com.jfinal.kit.StrKit;
import com.jfinal.render.Render;
import com.jfinal.render.RenderException;

/**
 * CaptchaRender.
 */
public class CaptchaRender extends Render {
	
	protected static String captchaName = "_jfinal_captcha";
	protected static final Random random = new Random(System.nanoTime());
	
	// 默认的验证码大小
	protected static final int WIDTH = 108, HEIGHT = 40;
	// 验证码随机字符数组
	protected static final char[] charArray = "3456789ABCDEFGHJKMNPQRSTUVWXY".toCharArray();
	// 验证码字体
	protected static final Font[] RANDOM_FONT = new Font[] {
		new Font(Font.DIALOG, Font.BOLD, 33),
		new Font(Font.DIALOG_INPUT, Font.BOLD, 34),
		new Font(Font.SERIF, Font.BOLD, 33),
		new Font(Font.SANS_SERIF, Font.BOLD, 34),
		new Font(Font.MONOSPACED, Font.BOLD, 34)
	};
	/*protected static final Font[] RANDOM_FONT = new Font[] {
		new Font("nyala", Font.BOLD, 38),
		new Font("Arial", Font.BOLD, 32),
		new Font("Bell MT", Font.BOLD, 32),
		new Font("Credit valley", Font.BOLD, 34),
		new Font("Impact", Font.BOLD, 32),
		new Font(Font.MONOSPACED, Font.BOLD, 40)
	};*/
	
	/**
	 * 设置 captchaName
	 */
	public static void setCaptchaName(String captchaName) {
		if (StrKit.isBlank(captchaName)) {
			throw new IllegalArgumentException("captchaName can not be blank.");
		}
		CaptchaRender.captchaName = captchaName;
	}
	
	/**
	 * 生成验证码
	 */
	public void render() {
		Captcha captcha = createCaptcha();
		CaptchaManager.me().getCaptchaCache().put(captcha);
		
		Cookie cookie = new Cookie(captchaName, captcha.getKey());
		cookie.setMaxAge(-1);
		cookie.setPath("/");
		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 {
			BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
			drawGraphic(captcha.getValue(), image);
			
			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);}
			}
		}
	}
	
	protected Captcha createCaptcha() {
		String captchaKey = getCaptchaKeyFromCookie();
		if (StrKit.isBlank(captchaKey)) {
			captchaKey = StrKit.getRandomUUID();
		}
		return new Captcha(captchaKey, getRandomString(), Captcha.DEFAULT_EXPIRE_TIME);
	}
	
	protected String getCaptchaKeyFromCookie() {
		Cookie[] cookies = request.getCookies();
		if (cookies != null) {
			for (Cookie cookie : cookies) {
				if (cookie.getName().equals(captchaName)) {
					return cookie.getValue();
				}
			}
		}
		return null;
	}
	
	protected String getRandomString() {
		char[] randomChars = new char[4];
		for (int i=0; i 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);
	}
	
	/**
	 * 校验用户输入的验证码是否正确
	 * @param controller 控制器
	 * @param userInputString 用户输入的字符串
	 * @return 验证通过返回 true, 否则返回 false
	 */
	public static boolean validate(Controller controller, String userInputString) {
		String captchaKey = controller.getCookie(captchaName);
		if (validate(captchaKey, userInputString)) {
			controller.removeCookie(captchaName);
			return true;
		}
		return false;
	}
	
	/**
	 * 校验用户输入的验证码是否正确
	 * @param captchaKey 验证码 key,在不支持 cookie 的情况下可通过传参给服务端
	 * @param userInputString 用户输入的字符串
	 * @return 验证通过返回 true, 否则返回 false
	 */
	public static boolean validate(String captchaKey, String userInputString) {
		ICaptchaCache captchaCache = CaptchaManager.me().getCaptchaCache();
		Captcha captcha = captchaCache.get(captchaKey);
		if (captcha != null && captcha.notExpired() && captcha.getValue().equalsIgnoreCase(userInputString)) {
			captchaCache.remove(captcha.getKey());
			return true;
		}
		return false;
	}
}











© 2015 - 2025 Weber Informatics LLC | Privacy Policy