學習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); }
明天繼續......