Jfinal框架登陆页面的图形验证码
本文转自,http://www.bubuko.com/infodetail-720511.html
验证码的工具类, 这个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"> </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> </td>
<td>
<INPUT TYPE="reset" name = "reset" value = "重 置">
<input type="submit" value="登陆"/>
</td>
</tr>
</table>
</form>
</div>
</body>
</html>
Jfinal框架登陆页面的图形验证码的更多相关文章
- 通过cookies跳过验证码登陆页面,直接访问网站的其它URL
我每次手动访问去NN网的一家酒店,就不需要登陆,一旦我用脚本打开就会让我登陆,而登陆页面又有验证码,不想识别验证码,所以就想:“通过cookies跳过验证码登陆页面,直接访问网站的其它URL” 转 ...
- Tornado框架实现图形验证码功能
图形验证码是项目开发过程中经常遇到的一个功能,在很多语言中都有对应的不同形式的图形验证码功能的封装,python 中同样也有类似的封装操作,通过绘制生成一个指定的图形数据,让前端HTML页面通过链接获 ...
- web系统登陆页面增加验证码
传统登陆页面中包含两个输入项: • 用户名 • 密码有时为了防止机器人进行自动登陆操作,或者防止恶意用户进行用户信息扫描,需增加动态验证码功能.此时,登陆页面中包含了三个输入项: • 用户名 • 密码 ...
- jsp登陆页面验证码在火狐浏览器不能刷新问题处理方案
jsp登陆页面在火狐浏览器验证码不能刷新问题处理方案: <img src="YzmServlet" onClick="this.src='YzmServlet?ti ...
- JEECG--去掉(增加)登陆页面验证码功能 - CSDN博客
JEECG--去掉(增加)登陆页面验证码功能 - CSDN博客https://blog.csdn.net/KooKing_L/article/details/79711379
- 一步一步实现web程序信息管理系统之二----后台框架实现跳转登陆页面
SpringBoot springboot的目的是为了简化spring应用的开发搭建以及开发过程.内部使用了特殊的处理,使得开发人员不需要进行额外繁锁的xml文件配置的编写,其内部包含很多模块的配置只 ...
- session过期跳转到登陆页面并跳出iframe框架的两个方法
最近在做拦截器,判断用户登录后操作超时,失去权限然后要重新登录,但是用的iframe,返回的登陆页总是在框架中显示,我百度了下,总是只有其中一个方法,现在分享下两种解决方法,希望对你们有帮助: 方法一 ...
- vue 项目,获取手机验证码和图形验证码(iviewUI框架)
1.编辑获取验证码模块 <Form ref="phoneFormItem" :model="phoneFormItem" :label-width=&qu ...
- java图形验证码生成工具类及web页面校验验证码
最近做验证码,参考网上案例,发现有不少问题,特意进行了修改和完善. 验证码生成器: import javax.imageio.ImageIO; import java.awt.*; import ja ...
随机推荐
- Luogu4191:[CTSC2010]性能优化
传送门 题目翻译:给定两个 \(n\) 次多项式 \(A,B\) 和一个整数 \(C\),求 \(A\times B^C\) 在模 \(x^n\) 意义下的卷积 显然就是个循环卷积,所以只要代入 \( ...
- apply的妙用
有一个很常见的问题"call和apply的区别是什么?",大家都知道答案:它们的区别仅在于接受参数的方式不同,传递给call的第二个参数必须逐个列举出来,而传递给apply的第二个 ...
- 001Spring Boot中使用MongoDB
01.下载MongoDB 点击标题链接,下载windows可用的MongoDB. 02.解压 将下载的压缩包放入C盘根目录(根据自己需要调整目录)---->解压到当前文件夹---->重命名 ...
- 131.006 Unsupervised Learning - Feature Scaling | 非监督学习 - 特征缩放
@(131 - Machine Learning | 机器学习) 1 Feature Scaling transforms features to have range [0,1] according ...
- Redis Windows环境启动
1.找到redis安装目录 2.cmd 目录 3.输入redis-server.exe redis.windows.conf 启动成功
- Python套接字
1.客户端/服务器架构 什么是客户端/服务器架构?对于不同的人来说,它意味着不同的东西,这取决于你问谁以及描述的是软件还是硬件系统.在这两种情况中的任何一种下,前提都很简单:服务器就是一系列硬件或软件 ...
- Avalon探索之旅
avalon2是一款基于虚拟DOM与属性劫持的 迷你. 易用. 高性能 的 前端MVVM框架, 拥有超优秀的兼容性, 支持移动开发, 后端渲染, WEB Component式组件开发, 无需编译, 开 ...
- 一些实用的adb命令
一.前提: 1.打开手机调试模式,确保手机已正常连接电脑,可在电脑上通过adb devices命令查看,结果如下说明连接成功: List of devices attached90xxxxc9 dev ...
- linux 三大利器 grep sed awk sed
sed主要内容和原理介绍 sed 流处理编辑器 sed一次处理一行内容,读入一行处理一行 sed不改变文件内容(除非重定向) sed 命令行格式 $ sed [options] 'command' f ...
- ETCD TLS 配置的坑
一.环境准备 环境总共 3 台虚拟机,系统为centos7,1个 master,2 个 etcd 节点,master 同时也作为 node 负载 pod,在分发证书等阶段将在另外一台主机上执行,该主机 ...