搜索 
 设为首页 加入收藏
当前位置>>开源人>>博客>>正文
《Blog开发文档》-管理员登录实现详解
作者: 发表日期:2008月01日27日 09:54 网友评论:0条 点击:3199

  

 管理员登录
  管理员登录我们使用到了ExtJS,进入页面为login.html,内容如下所示:
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>登录系统</title>
<link rel="stylesheet" type="text/css" href="plugins/extjs/ext-2.0/resources/css/ext-all.css" />
<link rel="stylesheet" type="text/css" href="stylesheet/ext-patch.css" />
<style type="text/css">
 .user{ background:url(images/user.gif) no-repeat 1px 2px; }
 .key{ background:url(images/key.gif) no-repeat 1px 2px;  }
 .key,.user{
  background-color:#FFFFFF;
  padding-left:20px;
  font-weight:bold;
  color:#000033;
 }
</style>
</head>
<body>
<div id="loading-mask" style="">
<div id="loading">
  <div style="text-align:center;padding-top:26%"><img src="images/extanim32.gif" width="32" height="32" style="margin-right:8px;" align="absmiddle"/>Loading...</div>
</div>
</div>
<script type="text/javascript" src="plugins/extjs/ext-2.0/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="plugins/extjs/ext-2.0/ext-all.js"></script>
<script src="javascript/adminLogin.js" type="text/javascript"></script>
</body>
</html>

  我们来重点看下面几个以ExtJS有关的代码:
  首先在<head>中使用<link rel="stylesheet" type="text/css" href="plugins/extjs/ext-2.0/resources/css/ext-all.css" />引入ExtJS的样式定义文件。
然后在<body>的开始使用了一个id为<div id="loading-mask">中的内容用于显示下面Loading图标的内容:

 
  接下来的代码是使用<script>引入该登录应用中涉及到的内个js文件,包括ext-base.js、ext-all.js这两个ExtJS框架的库文件,要使用ExtJS,就需要引入这两个库,当然如果你使用其它适配器,也可以引入类似ext-prototype-adapter.js这样的文件代替ext-base.js;然后引入adminLogin.js这个文件,该文件是管理员登录应用中使用到的js文件,也是该登录应用核心部分,下面我将会通过一小节来对adminLogin.js作详尽的讲解。

adminLogin.js代码及讲解

  adminLogin.js的目的在于显示一个登录表单,并在用户点击表单上的按钮时,向服务器端发送请求执行登录验证操作,如果登录成功,则导向后台管理主页面。要显示的登录表单如下图所示:
 
打开adminLogin.js,该文件一共包含四句代码。我们首先会看到下面的代码:
Ext.BLANK_IMAGE_URL = '../plugins/extjs/ext-2.0/resources/images/default/s.gif';
 Ext.QuickTips.init();//初始化鼠标停留时的显示框

  第一句用来指定空白图片的URL,由于该属性的默认值为http://extjs.com/s.gif,这样访问起来会有点慢;第二句代码用来初始化Ext的快速提示信息,这在我们提供表单按钮等验证的时候,Ext显示验证信息的时候其组件会用到。
  然后第三句代码是LoginWindow=Ext.extend(Ext.Window,{…});用来定义一个继承Ext.Window自定义窗口控件,从图可以看出,登录表单是一个带阴影的立体窗口,比传统的表单酷多了;由于把整个表单定义成了一个自定义的Ext控件类,因此在其它任何地方,我们想显示登录表单的时候,都可以直接new 一个LoginWindow的对象即可。
  adminLogin.js中的最后一句代码是Ext.onReady(function(){…});onReady是Ext类的一个全局静态方法,表示在文档html内容加载完后,DOM的onload方法执行及图片加载完之前执行要执行的函数。在这里我们是一个用function(){}定义的匿名函数,函数体的内容如下:

var win=new LoginWindow();
 win.show();
 setTimeout(function() {
    Ext.get('loading-mask').fadeOut( {
     remove : true
    });
   }, 300);

  首先使用new LoginWindow()来初始化一个登录窗口对象,并赋值给变量win,然后使用win.show()方法来显示这个窗口,最后一句是用来把login.html页面中用来显示加载信息的div从当前文档中删除掉。setTimeout 这个大家应该都知道,表示在多少毫秒后执行某一个函数,这里是一个匿名函数作为参数,匿名函数中的Ext.get('loading-mask')方法得到与文档中id为loading-mask的div对应的元素Element,然后执行元素的fadeOut方法实现显示一个淡出的渐变效果,参数remove:true表示效果执行完后把这个元素删除掉。

  现在我们看看登录程序中最核心的部分,也就是LoginWindow类的实现。首先使用Ext.extend(Ext.Window,{})表示继承Ext.Window类,后面大括号中的参数是指子类中的方法及属性等,由于LoginWindow类继承了Ext.Window,因此他就拥有了Ext.Window类的所有特性及功能,我们只需要给LoginWindow添加上具体的行为及特性即可,这个行为及特性出就是参数{}中定义的内容。下面我们来看看给LoginWindow类增加了哪些方法及属性。

首先,最前面的几个属性内容及说明分别如下:
title : '登陆系统',  //表示该窗口的标题默认显示为'登陆系统'
 width : 265,   //表示该窗口的默认宽度为265象素
 height : 140,  //表示该窗口的默认高度为140象素
 collapsible : true,//表示该窗口可以收缩起来
 defaults : {   //表示该窗口中所有子元素的特性
  border : false //表示所有子元素都不要显示边框
 },
buttonAlign : 'center', //表示该窗口的按钮为居中对齐方式

  然后接着为LoginWindow类定义了两个方法,第一个是createFormPanel,主要用来创建窗口中登录表单面板及具体的输入框等内容,代码及注释如下:
createFormPanel :function() {
  //直接使用new方法创建一个表单面板并返回
  return new Ext.form.FormPanel( {
   // 给面板的body元素指定自定义的CSS样式信息
   bodyStyle : 'padding-top:6px',
   // 表单面板中元素的默认类型
   defaultType : 'textfield',
   // 字段标签的默认对齐方式为右对齐
   labelAlign : 'right',
   // 指定标签的默认长度
   labelWidth : 55,
   // 标签与字段录入框之间的空白
   labelPad : 0,
   // 窗口是否显示背景色
   frame : true,
   // 表单面板容器中组件默认统一配置选项
   defaults : {
    // 验证字段是否能为空,这里为不允许为空
    allowBlank : false,
    // 字段默认宽度为158象素
    width : 158
   },
   // 指定表单面板容器中的元素,前面已经定义了默认为textfield
   items : [{
     // 给元素添加自定义的CSS样式user
     cls : 'user',
     // 字段的名称
     name : 'userName',
     // 指定字段的标签
     fieldLabel : '帐号',
     // 为空时提示信息
     blankText : '帐号不能为空'
    }, {
     // 给元素添加自定义的CSS样式key
     cls : 'key',
     // 字段的名称
     name : 'password',
      // 指定字段的标签
     fieldLabel : '密码',
// 为空时提示信息
     blankText : '密码不能为空',
// 指定字段的输入方式为password,也就输入时不会出现明文
     inputType : 'password'
    }]
  });
 }

  接下来定义LoginWindow类的第二个方法login,该方法是当用户点打击登录按钮时执行的代码,主要用来往服务器端发送数据,并根据服务器的返回情况,执行相应的功能,login方法中只有一句代码,即this.fp.form.submit({…}),直接调用表单面板fp上的表单位提交方法,执行表单提交操作,全部代码及注释如下:
login:function() {
   // 执行当前表单面板的submit
   this.fp.form.submit({//定义submit的参数选项
    // 动作发生期间默认等待对话框中显示的文本信息
     waitMsg : '正在登录......',
     // submit发生时指向的地址
     url : 'portal.ejf?cmd=adminLogin', 
     // 服务器端返回成功标注信息时,也就是验证通过时发生的动作
     success : function(form, action) {
      window.location.href = 'manage.ejf';//直接跳转到manage.ejf,也就是后台管理主程序
     },
     // 反之,如果登录验证失败,则执行failure中的指定的函数
     failure : function(form, action) {
      form.reset();//重置表单的内容,也就是把表单的reset一下
      if (action.failureType == Ext.form.Action.SERVER_INVALID)
       Ext.MessageBox.alert('警告', action.result.errors.msg);//如果是服务器端验证错误,也就是服务器返回false,则使用Ext.MessageBox的alert函数显示一个漂亮的验证错误信息提示框,验证信息的内容直接从服务器返回的result中读取
     }
    });
  }

  LoginWindow类的最后还有一个方法,也是Ext控件中非常重要的方法,即initComponent。该方法是Ext控件初始化时执行的方法,所有Ext可视化组件都包含该方法,每一个子类想添加自定义的控件信息,都可以重新定义该方法,但需要注意的一点是子类中重新定义的initComponent一定要调用父类的initComponent方法。下面LoginWindow方法的源代码:
initComponent : function(){
        LoginWindow.superclass.initComponent.call(this);      
        this.fp=this.createFormPanel();
        this.add(this.fp);
        this.addButton('登陆',this.login,this);
        this.addButton('重置', function(){this.fp.form.reset();},this);
  }  

  我们可以看到, initComponent的第一句LoginWindow.superclass.initComponent.call(this)就是直接调用子类的方法,你可以理解为像java中在子类构造函数中使用super()直接调用基类构造函数。

  第二行语句直接调用前台定义的createFormPanel方法,来获得一个表单面板对象,交赋值给LoginWindow对象的fp属性。然后使用this.add(this.fp)可以把该表单面板添加到窗口内容区;接着是调用this.addButton方法来在窗口中添加两个按钮。addButton是从父类Ext.Window的父类Ext.Panel(相当于爷爷类)继承来的。第一个参数表示按钮显示的名称,第二个参数表示点击该按钮时执行的回调函数,第三个参数表示回调函数执行的作用域。如果你对“回调函数”,“作用域”这些词不理解的话,还请赶紧补习javascript的基础知识。从代码中我们可以看到,登录按钮的回调函(也可以是事件响应函数或者事件处理器)数是this.login方法,也主前面定义的login方法,所以我们只要一点该按钮就会执行登录操作;而重置按钮的事件响应函数是一个匿名函数,匿名函数体的内容就是一句代码,即:this.fp.form.reset(),表示执行窗口中当前表单的重置操作。

  到这里,关于adminLogin.js的整个代码就讲解完了,你执行一下login.html,就能看到这个比较酷的登录表单效果了。


管理员登录后台

  在讲完了前台静态页面及相应js中的内容以后,现在来看看用于处理管理员登录的后台Java代码。
在前面的adminLogin.js的login方法中,提交表单时指定的url为portal.ejf?cmd=adminLogin,也主是说管理员登录验证由portal模块(PortalAction)中的adminLogin命令方法来处理,其代码如下:
public class PortalAction extends AbstractPageCmdAction {
private IBlogService blogService;
public Page doAdminLogin(WebForm form) {
  String name=CommUtil.null2String(form.get("userName"));
  boolean ret = blogService.adminLogin(name, CommUtil.null2String(form.get("password")));
  if (ret) {
   ActionContext.getContext().getSession().setAttribute("ADMIN","true");
  } else {
   this.addError("msg", "用户名或密码错误,请重新登录!");
  }
  return pageForExtForm(form);
 }
}

  后台代码直接通过form.get("userName")及form.get("password")得到用户名及密码,然后调用IBlogService(即blogService)中的adminLogin方法来验证管理登录信息。如果返回true,则表示验证通过,直接通过ActionContext来获得Session对象,并保存一个名称为ADMIN,值为TRUE的内容在Session中。如果登录出错,则直接使用 this.addError方法把错误信息保保存到当前上下文中。由于该Action是直接使用ExtJS来调用的,因此我们在方法的最后直接使用return pageForExtForm(form)方法来返回一个专为ExtJS Form的发起的数据请求提供数据的page。

再来玩一下LoginWindow

  前面不是说了LoginWindow是一个类吗,那么没有什么特殊情况(比如不是单例类)那么我们应该可以创建多个LoginWindow的实例了,Ext是基于面向对象编程的,很多组件的设计思想跟Java Swing中的组件设计非常相似。Javascript是一个面向对象的动态语言,可别小看他了。下面我们放松一下,把下面的代码添加到adminLogin.js中的Ext.onRead匿名函数参数的函数体内部,如下所示:

Ext.onReady(function()
{
 for(var i=0;i<20;i++)
 {
 var win=new LoginWindow({title:"登录窗口"+i,x:(i*30)});
 win.show();
 }
 setTimeout(function() {
    Ext.get('loading-mask').fadeOut( {
     remove : true
    });
   }, 300);
}
);
  再刷新一下login.html,你会得到类似下图所示的效果:
 
  哇,好多窗口啊,每个都有自己的标题,得来全不费工夫。你可拖动这些窗口,在每一个窗口中登录,执行各自的重置操作等,如下图所示:
 
  你可以通过传递配置参数title及x来改变窗口的标题及初始位置,当然还有其它更多有趣的东东,你得慢慢去发掘,这应该也是面向对象的好处。

下载:管理员登录实现详解.pdf


文章评论

当前暂时没有评论!
发表评论
您没有登录,不能发表评论,请先登录

网站简介 | 广告服务 | VIP资费标准 | 银行汇款帐号 | 网站地图 | 帮助 | 联系方式
地址:成都八宝街一号万和苑C座1203 电话:028-86272612 传真: 028-86272612
开源人网站版权所有  渝ICP备06004507号  建议使用1024*768分辨率