【电信计费系统项目实战】基础篇---登录界面实现
来源:互联网 发布:中国产业数据网 编辑:程序博客网 时间:2024/04/29 19:03
这一篇很简单,登录界面无非就是账号密码框再加上一个验证码,这里我们主要了解生成验证码及验证的基本原理,可以参考我之前写的一篇ajax注册页面异步验证。
登录界面代码:
<%@page pageEncoding="utf-8"%><%@taglib uri="/struts-tags" prefix="s" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>达内-NetCTOSS</title> <link type="text/css" rel="stylesheet" media="all" href="../styles/global.css" /> <link type="text/css" rel="stylesheet" media="all" href="../styles/global_color.css" /> <script type="text/javascript" language="javascript"> function change(imgObj) { imgObj.src = "createImage?date=" + new Date().getTime(); } </script> </head> <body class="index"> <div class="login_box"> <!-- method="post",保证中文不乱码 --> <form action="login" method="post"> <table> <tr> <td class="login_info">账号:</td> <td colspan="2"><input name="adminCode" type="text" value="<s:property value="adminCode"/>" class="width150" /></td> <td class="login_error_info"><span class="required">30长度的字母、数字和下划线</span></td> </tr> <tr> <td class="login_info">密码:</td> <td colspan="2"><input name="password" type="password" value="<s:property value="password"/>" class="width150" /></td> <td><span class="required">30长度的字母、数字和下划线</span></td> </tr> <tr> <td class="login_info">验证码:</td> <td class="width70"><input name="imageCode" type="text" class="width70" /></td> <td><img src="createImage" onclick="change(this)" alt="验证码" title="点击更换" /></td> <td><span class="required"></span></td> </tr> <tr> <td></td> <td class="login_button" colspan="2"> <a href="javascript:document.forms[0].submit();"><img src="../images/login_btn.png" /></a> </td> <td><span class="required"><s:property value="errorMsg"/></span></td> </tr> </table> </form> </div> </body></html>
代码解释:验证码图片那一行代码,通过点击超链接的方式来变换验证码图片上的验证码:
function change(imgObj) { imgObj.src = "createImage?date=" + new Date().getTime(); }
显而易见,通过createImage请求来变换验证码的,接着看到底是哪个Action用来生成验证码的:
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN" "http://struts.apache.org/dtds/struts-2.1.7.dtd"><struts> <!-- 登录模块 --> <package name="login" namespace="/login" extends="struts-default"> <!-- 跳转到登录页面Action。 该Action不需要写业务代码,class可以省略。 当class省略时,Struts2会自动调用ActionSupport, 这个类中有默认的方法execute,返回success。 --> <action name="toLogin"> <result name="success"> /WEB-INF/main/login.jsp </result> </action> <!-- 登录校验Action --> <action name="login" class="com.tarena.action.login.LoginAction"> <!-- 成功时跳转到首页 --> <result name="success"> /WEB-INF/main/index.jsp </result> <!-- 失败时回登录页 --> <result name="fail"> /WEB-INF/main/login.jsp </result> </action> <!-- 生成验证码Action --> <action name="createImage" class="com.tarena.action.login.CreateImageAction"> <result name="success" type="stream"> <!-- param是参数注入的标签,用于 给组件的属性注入值。这里相当于是给 stream类型的Result的inputName属性 设置值,其值为"imageStream". --> <param name="inputName"> imageStream </param> </result> </action> </package></struts>
以上是登录模块的struts配置,我们可以看到CreateImageAction类生成验证码操作
<!-- 生成验证码Action --> <action name="createImage" class="com.tarena.action.login.CreateImageAction"> <result name="success" type="stream"> <!-- param是参数注入的标签,用于 给组件的属性注入值。这里相当于是给 stream类型的Result的inputName属性 设置值,其值为"imageStream". --> <param name="inputName"> imageStream </param> </result> </action>
CreateImageAction完成的功能步骤:
- 生成图片
- 读取出验证码,并放入session
- 3.读取出图片
package com.tarena.action.login;import java.awt.image.BufferedImage;import java.io.IOException;import java.io.InputStream;import java.util.Map;import com.tarena.action.BaseAction;import com.tarena.util.ImageUtil;public class CreateImageAction extends BaseAction { //output private InputStream imageStream; public String execute() { //1.生成图片 Map<String, BufferedImage> map = ImageUtil.createImage(); //2.读取出验证码,并放入session String code = map.keySet().iterator().next(); session.put("imageCode", code); //3.读取出图片 BufferedImage image = map.get(code); try { imageStream = ImageUtil.getInputStream(image); } catch (IOException e) { e.printStackTrace(); return "error"; } return "success"; } public InputStream getImageStream() { return imageStream; } public void setImageStream(InputStream imageStream) { this.imageStream = imageStream; }}(map的keySet()方法返回值是Map中key值的集合)由此可以看出,具体完成验证码的是工具类ImageUtil,只不过CreateImageAction 调用它而已,它完成的功能有: 1. 用于生成一个图片,图片中带有验证码。 2. Map的key存的是验证码字符串 3. Map的value存的是图片此处灵活的运用map这个容器,非常方便的存取值。ImageUtil里都是java里最基本的知识,没什么好讲的,看看就行了:
package com.tarena.util;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.io.IOException;import java.io.InputStream;import java.util.HashMap;import java.util.Map;import java.util.Random;import com.sun.image.codec.jpeg.JPEGCodec;import com.sun.image.codec.jpeg.JPEGImageEncoder;public final class ImageUtil { private static final char[] chars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I' }; private static final int SIZE = 4; private static final int LINES = 5; private static final int WIDTH = 80; private static final int HEIGHT = 35; private static final int FONT_SIZE = 30; /** * 用于生成一个图片,图片中带有验证码。 * Map的key存的是验证码字符串, * Map的value存的是图片。 */ public static Map<String, BufferedImage> createImage() { StringBuffer sb = new StringBuffer(); BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); Graphics graphic = image.getGraphics(); graphic.setColor(Color.LIGHT_GRAY); graphic.fillRect(0, 0, WIDTH, HEIGHT); Random ran = new Random(); // 画随机字符 for (int i = 1; i <= SIZE; i++) { int r = ran.nextInt(chars.length); graphic.setColor(getRandomColor()); graphic.setFont(new Font(null, Font.BOLD + Font.ITALIC, FONT_SIZE)); graphic.drawString(chars[r] + "", (i - 1) * WIDTH / SIZE, 2*HEIGHT/3); sb.append(chars[r]);// 将字符保存,存入Session } // 画干扰线 for (int i = 1; i <= LINES; i++) { graphic.setColor(getRandomColor()); graphic.drawLine(ran.nextInt(WIDTH), ran.nextInt(HEIGHT), ran.nextInt(WIDTH), ran.nextInt(HEIGHT)); } Map<String, BufferedImage> map = new HashMap<String, BufferedImage>(); map.put(sb.toString(), image); return map; } public static Color getRandomColor() { Random ran = new Random(); Color color = new Color(ran.nextInt(256), ran.nextInt(256), ran.nextInt(256)); return color; } public static InputStream getInputStream(BufferedImage image) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bos); encoder.encode(image); byte[] imageBts = bos.toByteArray(); InputStream in = new ByteArrayInputStream(imageBts); return in; }}
然后就是登陆验证了,也没什么好讲的(代码如下),其他内容后面的章节会讲到。
package com.tarena.action.login;import org.omg.CORBA.Request;import com.tarena.action.BaseAction;import com.tarena.dao.DAOException;import com.tarena.dao.DAOFactory;import com.tarena.dao.login.ILoginDAO;import com.tarena.entity.Admin;public class LoginAction extends BaseAction { //input private String adminCode; private String password; private String imageCode; //output private String errorMsg; public String execute() { //1.校验验证码 String code = (String) session.get("imageCode"); if(code == null || !code.equalsIgnoreCase(imageCode)) { //验证码不匹配,校验失败 errorMsg = "验证码错误!"; return "fail"; } //2.根据账号查询管理员 ILoginDAO dao = DAOFactory.getLoginDAO(); Admin admin = null; try { admin = dao.findByCode(adminCode); } catch (DAOException e) { e.printStackTrace(); errorMsg = "查询管理员报错,请联系系统管理员!"; return "fail"; //异常,返回登录页面 } if(admin == null) { //3.如果没有对应的管理员,登录失败,账号不存在 errorMsg = "账号不存在!"; return "fail"; //验证失败,回登录页面 } else { //4.如果有对应管理员,看密码,若密码错误,登录失败 String pwd = admin.getPassword(); if(!pwd.equals(password)) { errorMsg = "密码错误!"; return "fail"; //验证失败,回登录页面 } } //4.登录成功后,将登录信息记录到Session session.put("admin", adminCode); return "success"; //成功,去index.jsp } public String getAdminCode() { return adminCode; } public void setAdminCode(String adminCode) { this.adminCode = adminCode; } public String getErrorMsg() { return errorMsg; } public void setErrorMsg(String errorMsg) { this.errorMsg = errorMsg; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getImageCode() { return imageCode; } public void setImageCode(String imageCode) { this.imageCode = imageCode; }}
很多网站都会加个验证码,比如百度贴吧啥的,验证码一般是防止有人利用机器人自动批量注册、对特定的注册用户用特定程序暴力破解方式进行不断的登陆、灌水。因为验证码是一个混合了数字或符号的图片,人眼看起来都费劲,机器识别起来就更困难。map可以很好的存取字符串和图片来实现验证码,所以这里主要了解map的用法就行啦!
5 4
- 【电信计费系统项目实战】基础篇---登录界面实现
- 【电信计费系统项目实战】基础篇---登录界面实现
- 【电信计费系统项目实战】基础篇---登录检查拦截器
- 【电信计费系统项目实战】基础篇---解析XML文件
- 【电信计费系统项目实战】基础篇---解析XML文件
- 【电信计费系统项目实战】介绍篇
- 【电信计费系统项目实战】基础篇---jdbc连接数据库代码
- 电信计费综合管理系统
- 河北省电信计费系统案例
- 新一代电信计费系统的演进
- 新一代电信计费系统的演进
- SparkStreaming 实现广告计费系统中在线黑名单过滤实战
- SparkStreaming 实现广告计费系统中在线黑名单过滤实战
- 客运综合管理系统项目—登录界面的实现
- 商城项目实战33:单点登录系统SSO实现
- RN实战项目登录界面(四)
- 主存数据库在电信计费帐务系统中的应用
- 电信计费帐务系统中-月租费计算程序分析
- html笔记
- PHP开发框架
- Scikit-learn 学习笔记
- Build Opus Codec for Android
- POJ 1258 Agri-Net
- 【电信计费系统项目实战】基础篇---登录界面实现
- Java常用类的总结
- oracle的查询数据表(二)
- angularJS 随手记
- 周期串问题(一)
- AIZU 2224 Save your cat
- 数据库小项目
- Angular 的 $http 跨域的问题
- PAT乙级.1041. 考试座位号(15)