您的位置:首页 > 编程语言 > Java开发

Extjs4学习笔记-ExtJS 4 图片验证码的实现(部分摘自《Extjs4.0学习指南(中文)》)andStruts2

2013-08-28 09:12 393 查看
上几篇文章,主要学习了 Extjs4 Grid 的使用方法,从本篇开始,我们开始其他组件的
学习,使用。在登录、注册甚至是发表文章或帖子的时候,都会用到验证码这个东西,那
么在 EXTJS 中,可以使用验证码功能么?答案是肯定的,在 EXTJS4 之前,也有很多验证
码的实现,在 Extjs4 中,验证码到底如何实现呢?
暂时,我们将验证码组件,命名为 CheckCode。此组件继承自 Ext.form.field.Text,在
实现之前,我们需要写两个样式,分别用来控制验证码的输入框和验证码图片的大小。
CSS 样式为:
Css代码  收藏代码
#CheckCode{ float:left;}
.x-form-code{width:73px;height:20px;vertical-align:middle;cursor:pointer; float:left; margin-left:7px;}
记住这两个样式的定义,后面,我们会用到它。
验证码的 JS 代码(CheckCode.js):

Js代码  收藏代码
Ext.define('SMS.view.CheckCode', {
extend: 'Ext.form.field.Text',
alias: 'widget.checkcode',
inputType: 'codefield',
codeUrl: Ext.BLANK_IMAGE_URL,
isLoader: true,

onRender: function(ct, position) {
this.callParent(arguments);
this.codeEl = ct.createChild({
tag: 'img',
src: Ext.BLANK_IMAGE_URL
});
this.codeEl.addCls('x-form-code');
this.codeEl.on('click', this.loadCodeImg, this);

if(this.isLoader) {
this.loadCodeImg();
}
},

aliasErrorIcon: function() {
this.errorIcon.alignTo(this.codeEl, 'tl-tr', [2, 0]);
},

loadCodeImg: function() {
//如果浏览器发现url不变,就认为图片没有改变,就会使用缓存中的图片,而不是重新向服务器请求,所以需要加一个参数,改变url
this.codeEl.set({
this.codeUrl  + '?id=' + Math.random()
});
}
});
以上代码中,定义了一个―类‖,名字是:SMS.view.CheckCode,其实这个名字,相当
于 extjs 3.x 之中的命名空间,以前也提到过。它继承自 Ext.form.field.Text,在它的
onRender 中,我们写了一些代码。其中 this.callParent(arguments);  代替了
xxxx.superclass.onRender.call(this, ct, position);在 Ext.form.field.Text 的基础上,使用
createChild 方法,创建了一个图片,并为其添加了一个名为 x-form-code,而后,给其创建
了一个 click 事件,这个事件实现的功能是,当我们点击验证码图片时,换另外一张图片,
也就是常说的:―看不清?换一张功能。‖,最后,如果 isLoader 为 True 时,调用
loadCodeImg 方法。至此,验证码功能全部完成了。下面,我们看看如何使用。
新建 Login.js 文件,定义―类‖SMS.view.Login,其全部代码为(Login.js):

Js代码  收藏代码
Ext.define('SMS.view.Login', {
extend: 'Ext.window.Window',
alias: 'widget.loginForm',
requires: [
'Ext.form.*',
'SMS.view.CheckCode'
],

initComponent: function() {

var checkcode = Ext.create('SMS.view.CheckCode', {
cls: 'key',
fieldLabel: '验证码',
name: 'checkcode',
id: 'checkcode',
allowBlank: false,
isLoader: true,
blankText: '验证码不能为空',
codeUrl: 'rand.action',
width: 160
});

var form = Ext.widget('form', {
border: false,
bodyPadding: 10,
fieldDefaults: {
labelAlign: 'left',
labelWidth: 55,
labelStyle: 'font-weight: bold'
},
defaults: {
margins: '0 0 10 0'
},
items: [{
xtype: 'textfield',
id: 'username',
name: 'username',
fieldLabel: '用户名',
blankText: '用户名不能为空',
allowBlank: false,
width: 240
}, {
xtype: 'textfield',
id: 'password',
name: 'password',
fieldLabel: '密   码',
allowBlank: false,
blankText: '密码不能为空',
width: 240,
inputType: 'password'
}, checkcode],

buttons: [{
text: '登录',
handler: function() {
//获取当前的表单form
var form = this.up('form').getForm();
//判断否通过了表单验证,如果不能空的为空则不能提交
if (form.isValid()) {
//alert("可以提交");
form.submit({
clientValidation : true,
waitMsg : '请稍候',
waitTitle : '正在验证登录',
url : 'login.action',
success : function(form, action) {
//登录成功后的操作,这里只是提示一下
Ext.MessageBox.show({
width : 150,
title : "登录成功",
buttons : Ext.MessageBox.OK,
msg : action.result.msg
})
},
failure : function(form, action) {
Ext.MessageBox.show({
width : 150,
title : "登录失败",
buttons : Ext.MessageBox.OK,
msg : action.result.msg
})
}
})
}
}
}, {
text: '取消',
handler: function() {
//点击取消,关闭登录窗口
// var form = this.up('form');
// form.close();
}
}]
});

Ext.apply(this, {
height: 160,
width: 280,
title: '用户登录',
closeAction: 'hide',
closable: false,
iconCls: 'login',
layout: 'fit',
modal: true,
plain: true,
resizable: false,
items: form
});
this.callParent(arguments);
}
});
程序的入口(app.js):

Js代码  收藏代码
Ext.application({
name: 'SMS',

appFolder: 'app',

launch: function() {
requires: ['SMS.view.Login']
var win;
win = Ext.create('SMS.view.Login').show();
}

});

login.jsp:
Jsp代码  收藏代码
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<base href="<%=basePath%>">

<title>用户登录</title>

<link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css" />
<script type="text/javascript" src="extjs/ext-all.js"></script>
<script type="text/javascript" src="extjs/ext-lang-zh_CN.js"></script>
<script type="text/javascript" src="app.js"></script>

<style type="text/css">
#checkcode {
float: left;
}

.x-form-code {
width: 73px;
height: 20px;
vertical-align: middle;
cursor: pointer;
float: left;
margin-left: 7px;
}
</style>

</head>

<body>
</body>
</html>
生成随机验证码的类( RandomNumUtil.java):

Java代码  收藏代码
package org.changkong.sms.utils;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;

/**
* 生成验证码的类文件
*
*/
public class RandomNumUtil {
private ByteArrayInputStream image;     //图像
private String str;     //验证码

private RandomNumUtil() {
init();     //初始化属性
}

/*
* 取得RandomNumUtil实例
*/
public static RandomNumUtil Instance() {
return new RandomNumUtil();
}

/*
* 取得验证码图片
*/
public ByteArrayInputStream getImage() {
return this.image;
}

/*
* 取得图片的验证码
*/
public String getString() {
return this.str;
}

private void init() {
//在内存中创建图象
//图像的高度和宽度
int width = 55, height = 20;
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
//获取图形上下文
Graphics g = image.getGraphics();
//生成随机类
Random random = new Random();
//设定背景色
g.setColor(getRandColor(200, 250));
g.fillRect(0, 0, width, 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(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
g.drawLine(x, y, x + xl, y + yl);
}
//取随机产生的认证码(6位数字)
String sRand = "";
for (int i = 0; i < 4; i++) {
String rand = String.valueOf(random.nextInt(10));
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);
}
//赋值验证码
this.str = sRand;

//图象生效
g.dispose();
ByteArrayInputStream input = null;
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
ImageOutputStream imageOut = ImageIO
.createImageOutputStream(output);
ImageIO.write(image, "JPEG", imageOut);
imageOut.close();
input = new ByteArrayInputStream(output.toByteArray());
} catch (Exception e) {
System.out.println("验证码图片产生出现错误:" + e.toString());
}
this.image = input;/* 赋值图像 */
}

/*
* 给定范围获得随机颜色
*/
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);
}
}
验证码的Action(SecurityCodeAction.java):

Java代码  收藏代码
package org.changkong.sms.action;

import java.io.ByteArrayInputStream;

import org.changkong.sms.utils.RandomNumUtil;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

/**
* 验证码的Action
* 使用SSH集成开发,Action由Spring管理
*/
@Controller("sercurityCodeAction")
@Scope("prototype")
public class SecurityCodeAction extends ActionSupport {

private ByteArrayInputStream inputStream;

public String execute() throws Exception {

RandomNumUtil rdnu = RandomNumUtil.Instance();

//取得带有随机字符串的图片
this.setInputStream(rdnu.getImage());

//取得随机字符串放入HttpSession
ActionContext.getContext().getSession().put("random", rdnu.getString());
return SUCCESS;
}

public void setInputStream(ByteArrayInputStream inputStream) {
this.inputStream = inputStream;
}

public ByteArrayInputStream getInputStream() {
return inputStream;
}

}
登录Action(LoginAction.java):
Java代码  收藏代码
package org.changkong.sms.action;

import org.apache.struts2.ServletActionContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.opensymphony.xwork2.ActionContext;

/**
* 登录Action
*/
@Controller("loginAction")
@Scope("prototype")
public class LoginAction {

private String username;
private String password;
private String checkcode; // 表单中的rand

//从session中取出RandomAction.java 中生成的验证码random
String arandom = (String) (ActionContext.getContext().getSession().get("random"));

public String execute() {

if(!arandom.equals(checkcode)) {
System.out.println("验证码不正确");
} else if(!"admin".equals(username)) {
System.out.println("用户不存在");
} else if("admin".equals(password)) {
System.out.println("密码错误");
}
return "success";

}

public String logout() {
ServletActionContext.getRequest().getSession().invalidate();
return "logout";
}

public String getCheckcode() {
return checkcode;
}

public void setCheckcode(String checkcode) {
this.checkcode = checkcode;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}
}
Struts.xml:

Xml代码  收藏代码
<!-- 用户登陆 -->
<action name="login" class="loginAction">
<!-- LoginAction无需经过LoginInterceptor -->
<interceptor-ref name="defaultStack"></interceptor-ref>
<result name="success" type="redirect">/main.jsp</result>
<result name="fail">/login.jsp</result>
<result name="logout">/login.jsp</result>
</action>

<!-- Random验证码 -->
<action name="rand" class="sercurityCodeAction">
<result type="stream">
<param name="contentType">image/jpeg</param>
<param name="inputName">inputStream</param>
</result>
</action>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  estjs
相关文章推荐