| 站点地图 | 联系我
| www.asm32.net | 2006版 | 资料中心 | linux | asm/asm32 | C/C++ | VC++ | java | 书签 | ASP.Net书签 | 上善若水 厚德载物
 现在位置 :: 主页 >> 资料中心 >> ROOT / CODE / Java /
 

Jfinal框架登陆页面的图形验证码

来源(博客园)

From: http://www.cnblogs.com/sunhaoyu/p/4391277.html

Jfinal框架登陆页面的图形验证码

一个验证码搞了一上午, 终于在终于在网上借鉴各位大侠的文章写出来了。郁闷的心情有所好转, 记下来以后或许还能用到 (*^__^*) ……

验证码的工具类, 这个jfinal自带的也有,但是下面这个和Jfinal自带的有一点点小的改动,(我用Jfinal自带的,在action中判断输入的验证码和系统随机生成的做对比的时候,出了问题。自带的类好像要用到MD5加密手动输入的验证码后才能判断,(这个我也不太清楚,只是我的感觉 -,- !,真希望能有位好心人为我这样的菜鸟解答一下。))。呜,这个类也是在网上找的文章产考改的。。

package com.springscapital.console.ext.render;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.security.MessageDigest;
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.StringKit;
import com.jfinal.render.Render;
/**
*
* @author Administrator
*    图形验证类
*/
public class MyCaptchaRender extends Render
{
	private static final long serialVersionUID = -7599510915228560611L;
	private static final String[] strArr = {"3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E",
		"F", "G", "H", "J", "K", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y"};
	private static String randomCodeKey = "JFINAL_JLHHWH_Key";
	private static boolean caseInsensitive = true;
	private int img_width = 85;
	private int img_height = 20;
	private int img_randNumber = 6;
	public MyCaptchaRender() {
	}
	public MyCaptchaRender(String randomKey) {
		if (StringKit.isBlank(randomKey))
			throw new IllegalArgumentException("randomKey can not be blank");
		randomCodeKey = randomKey;
	}
	public MyCaptchaRender(int width, int height, int count, boolean isCaseInsensitive) {
		if(width <=0 || height <=0 || count <=0)
		{
			throw new IllegalArgumentException("Image width or height or count must be > 0");
		}
		this.img_width = width;
		this.img_height = height;
		this.img_randNumber = count;
		caseInsensitive = isCaseInsensitive;
	}
	public MyCaptchaRender(String randomKey,int width, int height, int count, boolean isCaseInsensitive) {
		if (StringKit.isBlank(randomKey))
			throw new IllegalArgumentException("randomKey can not be blank");
		randomCodeKey = randomKey;
		if(width <=0 || height <=0 || count <=0)
		{
			throw new IllegalArgumentException("Image width or height or count must be > 0");
		}
		this.img_width = width;
		this.img_height = height;
		this.img_randNumber = count;
		caseInsensitive = isCaseInsensitive;
	}
	public void render() {
		BufferedImage image = new BufferedImage(img_width, img_height, BufferedImage.TYPE_INT_RGB);
		String vCode = drawGraphic(image);
		vCode = encrypt(vCode);
		Cookie cookie = new Cookie(randomCodeKey, vCode);
		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 {
			sos = response.getOutputStream();
			ImageIO.write(image, "jpeg",sos);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		finally {
			if (sos != null)
				try {sos.close();} catch (IOException e) {e.printStackTrace();}
		}
	}
	private String drawGraphic(BufferedImage image){
		// 获取图形上下文
		Graphics g = image.createGraphics();
		// 生成随机类
		Random random = new Random();
		// 设定背景色
		g.setColor(getRandColor(200, 250));
		g.fillRect(0, 0, img_width, img_height);
		// 设定字体
		g.setFont(new Font("Times New Roman", Font.PLAIN, 18));
		// 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
		g.setColor(getRandColor(160, 200));
		for (int i = 0; i < 155; i++) {
			int x = random.nextInt(img_width);
			int y = random.nextInt(img_height);
			int xl = random.nextInt(12);
			int yl = random.nextInt(12);
			g.drawLine(x, y, x + xl, y + yl);
		}
		// 取随机产生的认证码(img_randNumber位数字)
		String sRand = "";
		for (int i = 0; i < img_randNumber; i++) {
			String rand = String.valueOf(strArr[random.nextInt(strArr.length)]);
			sRand += rand;
			// 将认证码显示到图象中
			g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
			// 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
			g.drawString(rand, 13 * i + 6, 16);
		}
		// 图象生效
		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);
	}

	private static final String encrypt(String srcStr) {
		try {
			String result = "";
			MessageDigest md = MessageDigest.getInstance("MD5");
			byte[] bytes = md.digest(srcStr.getBytes("utf-8"));
			for(byte b:bytes){
				String hex = Integer.toHexString(b&0xFF).toUpperCase();
				result += ((hex.length() ==1 ) ? "0" : "") + hex;
			}
			return result;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static boolean validate(Controller controller, String inputRandomCode) {
		if (StringKit.isBlank(inputRandomCode))
			return false;
		try {
			if(caseInsensitive)
			inputRandomCode = inputRandomCode.toUpperCase();
			inputRandomCode = encrypt(inputRandomCode);
			return inputRandomCode.equals(controller.getCookie(randomCodeKey));
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

}


Action 中的代码 :

package com.springscapital.console.site.controller;

import com.jfinal.core.Controller;
import com.springscapital.console.ext.render.MyCaptchaRender;

public class HomeController extends Controller{
	public void index() {
		render("/site/login.html");
	}
	//验证输入的和系统生成的验证码是否一样
	public void login() {
		String inputRandomCode = getPara("captcha");
		boolean validate = MyCaptchaRender.validate(this, inputRandomCode);
		System.out.println("CaptchaRender.validate=" + validate + ";inputRandomCode=" + inputRandomCode);
	}
	//生成图片
	public void captcha(){
		render(new MyCaptchaRender(60,22,4,true));
	}

}


接下来就是页面中的代码了, 这个我也好纠结,本来想加个看不清换一张的按钮然后用ajax异步刷新验证码的,可惜没实现,页面中被我注释掉的代码就是我用的ajax,但是没搞出来,又有点小郁闷了,希望哪位大神看到了能为小弟解惑。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!-- <script type="text/javascript" src="${ctx!}/static/js/jquery-1.8.3.js"></script>
<script type="text/javascript">
$(function() {
	$(".sumbit").click(
		function() {
			$.ajax( {
					url : "${ctx!}/site/captcha",//发送请求的地址
					data : {
						account : $("#captcha").val()//发送到服务器的数据
					},
					error : function() {
						alert("error: 网络异常请稍后再尝试!!!");//请求失败时弹出的信息
					}
					success : function(data) {//返回的信息展示出来
						$(".hint").html(data);//请求成功时,调用的函数
					}
			});
	});
});</script> -->
</head>
<body>
<div class="main" align="center">
	<form action="${ctx!}/site/login" method="post">
		<table>
			<tr>
				<td>用户名:</td>
				<td><input type="text" name="username"/></td>
			</tr>
			<tr>
				<td>密   码:</td>
				<td><input type="password" name="pwd"/></td>
			</tr>
			<tr>
				<td><img src="${ctx!}/site/captcha">&nbsp;</td>
				<td>
					<input type="text"id="captcha" name="captcha" value=""/>
					<!-- <input class="sumbit" type="button" value="看不清换一张">
					<input type=button value=刷新 onclick="location.reload()">  -->                        
				</td>
			</tr>
			<tr>
				<td>&nbsp;</td>
				<td>
					<INPUT TYPE="reset" name = "reset" value = "重 置"> 
					&nbsp;&nbsp;&nbsp;
					<input type="submit" value="登陆"/>
				</td>
			</tr>
		</table>
	</form>
</div>     
</body>
</html>


页面展示:



分类: jfinal

Link: http://www.asm32.net/article_details.aspx?id=7259


浏览次数 0 发布时间 2017/8/9 22:35:11 从属分类 Java 【评论】【 】【打印】【关闭
 
| www.asm32.net | 2006版 | 资料中心 | linux | asm/asm32 | C/C++ | VC++ | java | 书签 | ASP.Net书签 | 京ICP备09029108号-1