estore商城案例(一)------用户注册&邮件激活(上)
学习javaweb时间不长,也是第一次发博客,有写的不好的地方请大家多多指出.最近,根据老师上课讲的和自己的想法最终是把estore这个网上商城小案例完成了,所以总结一下放到博客上,希望对像我一样的初学者有所帮助.好了,下面开始正题.
涉及到的功能:
1、注册&邮箱激活
2、登录&添加商品&商品列表
3、过滤器:自动登录&权限管理
4、添加购物车&购物车显示
5、生成订单&在线支付
一、注册&邮箱激活
先展示一下效果:
1、注册首页的用户名、邮箱、验证码都做了ajax提交到服务器去验证。
2、提交注册信息,激活邮件.哦哦,下面的页面没显示多少秒,待会再解决.
数据库中看到刚才注册的用户状态为0,还未激活
打开Foxmail接收邮件,点击激活,激活后数据库中的状态将变为1,然后跳转到登陆界面登陆.
二、数据库涉及到的表
1、users表:
create database estoresystem; use estoresystem; create user estore identified by 'estore'; grant all on estoresystem.* to estore; CREATE TABLE users ( id int(11) NOT NULL AUTO_INCREMENT, username varchar(100) NOT NULL, password varchar(100) NOT NULL, nickname varchar(100) DEFAULT NULL, email varchar(100) NOT NULL, state int(11) DEFAULT NULL, role varchar(10) DEFAULT NULL, activecode varchar(100) DEFAULT NULL, registtime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id) )
三、在myeclipse中创建工程,开始撸代码。
1、创建数据库连接,使用c3p0连接池,在utils包装创建JdbcUtils类,负责调用数据库资源。当然使用c3p0需要先在src下创建和配置c3p0的xml文件.
public class JdbcUtils { private static DataSource dataSource = new ComboPooledDataSource(); public static Connection getConnection() { try { return dataSource.getConnection(); } catch (SQLException e) { e.printStackTrace(); } return null; } public static DataSource getDataSource() { return dataSource; }
2、在domain包里创建users表的实体类User,以及操作users的dao。dao包下存放interface UserDao,dao.impl包下存放UserDao接口的实现类UserDaoImpl。
接口:
public interface UserDao { //增删改 public abstract boolean executeUpate(String sql, Object... param); public abstract boolean add(User u); public abstract boolean deleteByActivecode(User u); public abstract boolean updateState(User u); //单查询 public abstract User queryUser(String key, String values); public abstract User querUserByActivecode(User u); public abstract User loginByUser(User u); }
接口实现类
public class UserDaoImpl implements UserDao { //增删改通用方法 @Override public boolean executeUpate(String sql,Object...param) { QueryRunner runner=new QueryRunner(JdbcUtils.getDataSource()); int i=0; try { i=runner.update(sql, param); } catch (SQLException e) { e.printStackTrace(); } return i>0?true:false; } //增 @Override public boolean add(User u) { String sql="insert into users values(null,?,?,?,?,0,'user',?,null)"; Object[] param={u.getUsername(),MD5.getMD5(u.getPassword()),u.getNikename(),u.getEmail(),u.getActivecode()}; return executeUpate(sql, param);//使用的上面的增删改通用方法 } //单查询通用方法 @Override public User queryUser(String key,String values) { QueryRunner runner=new QueryRunner(JdbcUtils.getDataSource()); String sql="select * from users where "+key+"=?"; try { return runner.query(sql, new BeanHandler<User>(User.class), values); } catch (SQLException e) { e.printStackTrace(); throw new MyRuntimeException(e); } } //根据激活码查询用户 @Override public User querUserByActivecode(User u) { return queryUser("activecode", u.getActivecode());//使用的上面的单查询通用方法 } //用户登录时使用 @Override public User loginByUser(User u) { QueryRunner runner=new QueryRunner(JdbcUtils.getDataSource()); String sql="select * from users where username=? and password=?"; try { return runner.query(sql, new BeanHandler<User>(User.class), u.getUsername(),u.getPassword()); } catch (SQLException e) { e.printStackTrace(); throw new MyRuntimeException(e); } } }
四、下面开始写web层
1、注册页面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>注册首页</title> <script type="text/javascript" src="js/validate.js"></script>//这个js文件是ajax <script type="text/javascript"> function vCode() { document.getElementById("showCode").src = "${pageContext.request.contextPath }/validateCode?" + new Date(); } function valide() { var doc=document.getElementsByTagName("input"); for(var i=0;i<doc.length-1;i++) { check(doc[i]); }//这里的写法存在js闭包问题,当然这里没影响.本来我是打算在window.onload的方法中for循环动态给下面的input的方法添加onblur事件的,但是由于闭包问题,无法实现,虽然用匿名函数的方法可以解决,但是代码就太臃肿了,最终还是在标签后手动添加onblur事件了. if (STATUS ==true&&USERNAME == true && PASSWORD == true && REPASSWORD == true && NIKENAME == true && EMAIL == true && VALIDATE == true) { return true; } else{ return false; } } var USERNAME = false; var PASSWORD = false; var REPASSWORD = false; var NIKENAME = false; var EMAIL = false; var VALIDATE = false; var STATUS = false; function check(obj) { var filter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/; var password = document.getElementById("password").value; var span_id = obj.id + "_msg"; if (obj.value == "") { document.getElementById(span_id).innerHTML = "<font color='red'>不能为空</font>"; STATUS=false; return; } else { STATUS = true; if (obj.id == "username") { validate("username", obj.value); var b=document.getElementById("hidden").value;//这里的hidden值是从ajax中获取,下面js代码中有详细解释 if (b=="false")//返回false验证失败 { document.getElementById(span_id).innerHTML = "<font color='red'>用户名不可用</font>"; USERNAME = false; return; } document.getElementById(span_id).innerHTML = "<font color='green'>用户名可用</font>"; USERNAME = true; return; } if (obj.id == "password") { document.getElementById(span_id).innerHTML = ""; PASSWORD = true; return; } if (obj.id == "repassword") { if (obj.value != password && obj.value != "") { document.getElementById(span_id).innerHTML = "<font color='red'>两次输入的密码不一致</font>"; REPASSWORD = false; return; } document.getElementById(span_id).innerHTML = ""; REPASSWORD = true; return; } if (obj.id == "nikename") { document.getElementById(span_id).innerHTML = ""; NIKENAME = true; return; } if (obj.id == "email") { if (!filter.test(obj.value)) { document.getElementById(span_id).innerHTML = "<font color='red'>邮箱格式不正确</font>"; EMAIL = false; return; } else { validate("email", obj.value); var b=document.getElementById("hidden").value; if (b=="false")//返回false验证失败 { document.getElementById(span_id).innerHTML = "<font color='red'>邮箱已被注册</font>"; EMAIL = false; return; } document.getElementById(span_id).innerHTML = "<font color='green'>邮箱可用</font>"; EMAIL = true; return; } } if (obj.id == "validatecode") { validate("validatecode", obj.value); var b=document.getElementById("hidden").value; if (b=="false")//返回false验证失败 { document.getElementById(span_id).innerHTML = "<font color='red'>验证码错误</font>"; VALIDATE = false; return; } document.getElementById(span_id).innerHTML = "<font color='green'>Ok</font>"; VALIDATE = true; return; } } } </script> </head> <body> <center> <div>用户注册</div> <hr> <form action="${pageContext.request.contextPath }/regist" onsubmit="return valide();" method="post"> <table> <tr> <th>用户名</th> <td><input type="text" name="username" id="username" onblur="check(this);"><span id="username_msg"></span></td> </tr> <tr> <th>密码</th> <td><input type="password" name="password" id="password" onblur="check(this);"><span id="password_msg"></span></td> </tr> <tr> <th>重复密码</th> <td><input type="password" id="repassword" onblur="check(this);"><span id="repassword_msg"></span></td> </tr> <tr> <th>昵称</th> <td><input type="text" name="nikename" id="nikename" onblur="check(this);"><span id="nikename_msg"></span></td> </tr> <tr> <th>邮箱</th> <td><input type="text" name="email" id="email" onblur="check(this);"><span id="email_msg"></span></td> </tr> <tr> <th>验证码</th> <td><input type="text" id="validatecode" onblur="check(this);"><img alt="验证码" id="showCode" src="${pageContext.request.contextPath }/validateCode" style="cursor: pointer;" onclick="vCode();"><span id="validatecode_msg"></span></td> </tr> <tr> <td colspan="2"><input type="submit" value="提交"></td> <input type="hidden" id="hidden"> </tr> </table> </form> </center> </body> </html>
function validate(key,values) { var xmlHttp=ajaxFunction();//这里是获取ajax对象的方法,我没写 xmlHttp.onreadystatechange=function() { if(xmlHttp.readyState==4&&xmlHttp.status==200) { var b=xmlHttp.responseText; document.getElementById("hidden").value=b; //对于这里的问题是,我本来是想直接把responseText的值回传给主调函数的,但是始终无法获得,问题的原因还未知,待查证.最后我在form表单中添加了一个hidden标签,把responseText的值传给hidden的value,然后主调函数直接调用hidden的value就可以了 } } xmlHttp.open("get","/myestore/regist?"+key+"="+values,false); xmlHttp.send(null); }
明天继续......