富浏览器程序设计实例 -页面控制 - 登录与验证码
登录与验证涉及8个文件,罗列如下:
login.jscheckCode.cssLoginAction.javaLoginService.javaLoginServiceImpl.javaLoginDao.javaLoginDaoImpl.javaUser.java
在登录的模块中首先应当验证验证码的正确性,然后在查阅数据库内容。如果仅仅是简单的登录验证,实际上和Session并没有关系,但是如果你要控制页面,不让他随便跳转,这就和Session有关了。举例来说:登录页是login.jsp,登录完成,借助struts你会跳转到对应的页面。但是如果你直接在地址栏输入你要去的页面,你可以直接进入。这在很多系统中是不允许的。为了达到这个目的,我们需要对页面进行拦截和过滤,Servlet中提供了一个类是Filter类,专门做这件事。在这里先介绍登录与验证的实现方法,过滤的功能 将在《页面Filter拦截与过滤》介绍,因为有些可写的。这篇文章是对《SSH2+ExtJS4.2.1+MySql示例程序》系列博客的完善,在这篇博客中提供的源代码也将更新,但源地址连接会保留。新的源代码中将会增加对登录、验证和页面拦截与过滤的功能。
针对源代码在CSDN中的积分设置仍然是20分,分成两个压缩包,每个10分。这样设置的原因是:1.CSDN初始20分,如果你只是个伸手党,没有开源精神,不做贡献,你的CSDN积分肯定不够20分,那么资源不会分享给你;2.下载资源,评论下,系统会返还你的积分,也就是说对你并没有损失;3.作者耗费精力从无到有,算是另一种收获吧。
在login()方法中ajaxJson()方法是向服务器发送消息的
对前台脚本的处理
关于Struts2的属性映射原理,页面中定义的属性只要和对应要访问的Action中的属性相同即可,这里相同指大小写也要一致。在ExtJS中 定义的name:'username',属性,在Action中也要有对应的字段。从请求的页面将要发送的值传送到Action中是通过Struts2来做的,Struts2就像一个信息传递的使者。知道该这么用就好,没必要深究太多。
相关资源将会在12月2日之前更新,在《SSH2+ExtJS4.2.1+MySql示例程序》下面会给出新的资源链接。针对用户登录与页面控制是一组完整的逻辑,这篇文章先介绍登录与验证,今天晚上在更新《页面Filter拦截与过滤》的内容,如果对您有帮助,帮忙点个赞~
在login()方法中ajaxJson()方法是向服务器发送消息的
- /**
- * trim()方法用于去除空格
- * 1. 判断验证码正确性
- * 2. 判断用户名在数据库中是否存在
- * 3. 判断密码是否正确
- */
- public void login()
- {
- String msg = "";
- // 判断验证码正确性
- String actionCheckCode = (String) ActionContext.getContext().getSession().get("getRandomNum");
- if ( !pageCheckCode.equals(actionCheckCode) )
- {
- msg = "{success:false,failMessage:'验证码有误'}";
- }
- else
- {
- try
- {
- // 判断用户名在数据库中是否存在
- user = loginService.get(User.class, "username", username.trim());
- if (user != null)
- {
- // if ( passwordMd5.trim().equals(user.getPassword().trim()) ) // TODO 2013-11-18
- if ( password.trim().equals(user.getPassword().trim()) )
- {
- msg = "{success:true}";
- this.userSession();
- }
- else{
- msg = "{success:false,failMessage:'密码不正确'}";
- }
- }
- else {
- msg = "{success:false,failMessage:'系统无此用户'}";
- }
- }
- catch (Exception e)
- {
- msg = "{success:false, failMessage:'登录失败,请确认网络或数据库是否正常!'}";
- }
- }
- ajaxJson(msg);
- }
验证码生成方法,作为LoginAction.java中的一个独立方法,当你在浏览器地址栏中输入如下连接的时候,页面中会出现一个图片,图片中包含验证码
http://localhost:8099/system/login!sendCheckCode.action
http://localhost:8099/system/login!sendCheckCode.action
- /**
- * 生 成随机验证码 这是一个独立的 Action 方法
- */
- public void sendCheckCode() throws IOException
- {
- //设置页面不缓存
- HttpServletResponse response = getUTFResponse(); //ServletActionContext.getResponse();
- response.setHeader("Pragma", "No-cache");
- response.setHeader("Cache-Control", "no-cache");
- response.setHeader("Content-Type", "image/jpeg");
- response.setDateHeader("Expires", 0);
- // 在内存中创建图象
- int width = 60, 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);
- }
- // 取随机产生的认证码(4位数字)
- String randomNum = "";
- for (int i = 0; i < 4; i++)
- {
- String getRandomNum = String.valueOf(random.nextInt(10));
- randomNum += getRandomNum;
- // 将认证码显示到图象中
- g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
- // 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
- g.drawString(getRandomNum, 13 * i + 6, 16);
- }
- System.out.println("randomNum = " + randomNum);
- // 将认证码存入SESSION
- ActionContext.getContext().getSession().put("getRandomNum", randomNum);
- // 图象生效
- g.dispose();
- OutputStream output = response.getOutputStream();
- try
- {
- // 输出图象到页面
- ImageIO.write(image, "JPEG", output);
- }
- finally {
- output.flush();
- output.close();
- }
- }
- //获得随机颜色 给定范围获得随机颜色
- // java.awt.Color
- 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);
- }
后台查询用户调用的方法:
- /**
- * 根据属性名和属性值获取实体对象.
- *
- * @param clazz 实体对象类型
- * @param propertyName 属性名称
- * @param value 属性值
- * @return 实体对象
- */
- @SuppressWarnings("unchecked")
- public <T> T get(Class<T> clazz, String propertyName, Object value)
- {
- Assert.hasText(propertyName, "propertyName must not be empty");
- Assert.notNull(value, "value is required");
- String hql = "from " + clazz.getName() + " as model where model." + propertyName + " = ?";
- return (T) getSession().createQuery(hql).setParameter(0, value).uniqueResult();
- }
- }
对前台脚本的处理
- var loginForm = Ext.create('Ext.FormPanel',
- {
- height:100,
- width:300,
- frame:true,
- baseCls:'x-plain',
- items:
- [
- {
- xtype:'textfield',
- value:'a',
- name:'username', // 要对应LoginAction里的username
- fieldLabel:'用户名',
- labelWidth:60,
- width:250,
- padding:'5 20 5 20',
- allowBlank:false,
- blankText:'用户名不能为空',
- msgTarget:'side'
- },
- {
- xtype:'textfield',
- value:'a',
- name:'password',
- itemId:'password',
- inputType:'password',
- fieldLabel:'密 码',
- labelWidth:60,
- width:250,
- padding:'10 20 5 20',
- allowBlank:false,
- blankText:'密码不能为空',
- msgTarget:'side'
- },
- {
- xtype:'textfield', // 隐藏字段 用于将密码铭文加密
- itemId:'passwordMd5',
- name:'passwordMd5',
- width:0,
- hidden:true
- },
- checkcode
- ]
- });
关于Struts2的属性映射原理,页面中定义的属性只要和对应要访问的Action中的属性相同即可,这里相同指大小写也要一致。在ExtJS中 定义的name:'username',属性,在Action中也要有对应的字段。从请求的页面将要发送的值传送到Action中是通过Struts2来做的,Struts2就像一个信息传递的使者。知道该这么用就好,没必要深究太多。
相关资源将会在12月2日之前更新,在《SSH2+ExtJS4.2.1+MySql示例程序》下面会给出新的资源链接。针对用户登录与页面控制是一组完整的逻辑,这篇文章先介绍登录与验证,今天晚上在更新《页面Filter拦截与过滤》的内容,如果对您有帮助,帮忙点个赞~