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

本文涉及的产品
简介:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
上几篇文章,主要学习了 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>
本文转自yunlielai51CTO博客,原文链接: http://blog.51cto.com/4925054/1284020 ,如需转载请自行联系原作者
相关实践学习
基于函数计算一键部署掌上游戏机
本场景介绍如何使用阿里云计算服务命令快速搭建一个掌上游戏机。
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
相关文章
|
JavaScript 前端开发 Windows
网页标题乱码的解决办法 JAVASCRIPT入门书籍推荐
网页标题乱码的解决办法 JAVASCRIPT入门书籍推荐
103 0
|
移动开发 安全 JavaScript
html5—史上最全的知识点
html5—史上最全的知识点
html5—史上最全的知识点
|
JavaScript 前端开发 API
|
前端开发 JavaScript .NET
|
前端开发 JavaScript Web App开发
|
JavaScript 数据格式 XML
|
Web App开发 前端开发 JavaScript
|
JavaScript 前端开发
《jQuery Cookbook中文版》——1.16 获取和设置文本内容
重要的一点是,要记住text()方法与html()方法没有什么不同,唯一的例外是text()方法将对HTML进行转义(将<和>替换为HTML实体)。这意味着,如果在text()方法的字符串参数中放入标记,该方法会将这些标记转换为HTML实体(&lt;和&gt;)。
1000 0