一.项目介绍
1.项目页面原型下载
书城项目页面原型可以直接从gitee上下载:https://gitee.com/ouyi19940129/BookStore.git
2.项目页面原型目录讲解
二.阶段1:jQuery实战
1.需求:
2.实现:
(1)使用IDEA创建web项目
-
先创建一个普通java项目
-
在该项目中引入web
classes用于存放编译后的文件,lib存放第三方jar包
- 将项目页面原型代码复制到web目录下
(2)使用jQuery实现登录页面的用户名密码非空校验
- 在
pages/user/login.html
中引入jquery-1.7.2.js
和login.js
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>尚硅谷会员登录页面</title> <link type="text/css" rel="stylesheet" href="../../static/css/style.css" /> <script type="text/javascript" src="../../static/script/jquery-1.7.2.js"></script> <script type="text/javascript" src="../../static/script/login.js"></script> </head> <body> <div id="login_header"> <a href="../../index.html"> <img class="logo_img" alt="" src="../../static/img/logo.gif" /> </a> </div> <div class="login_banner"> <div id="l_content"> <span class="login_word">欢迎登录</span> </div> <div id="content"> <div class="login_form"> <div class="login_box"> <div class="tit"> <h1>尚硅谷会员</h1> </div> <div class="msg_cont"> <b></b> <span class="errorMsg">请输入用户名和密码</span> </div> <div class="form"> <form action="login_success.html"> <label>用户名称:</label> <input class="itxt" type="text" placeholder="请输入用户名" autocomplete="off" tabindex="1" name="username" id="username" /> <br /> <br /> <label>用户密码:</label> <input class="itxt" type="password" placeholder="请输入密码" autocomplete="off" tabindex="1" name="password" id="password" /> <br /> <br /> <input type="submit" value="登录" id="sub_btn" /> </form> <div class="tit"> <a id = "submit" href="regist.html">立即注册</a> </div> </div> </div> </div> </div> </div> <div id="bottom"> <span> 尚硅谷书城.Copyright ©2015 </span> </div> </body> </html>
- 在
static/script/
目录下创建login.js
文件$(function () { /** * 检查用户名函数 */ function checkUsernamePassword() { var username = $("#username").val(); var password = $("#password").val(); if (username == "" || password == "") { alert("用户名密码不能为空"); return false; } } /** * 点击登录按钮事件函数 */ $("#sub_btn").click(checkUsernamePassword); })
(3)使用jQuery实现注册页面校验
- 在
pages\user\regist.html
文件中引入jquery-1.7.2.js
和regist.js
文件<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>尚硅谷会员注册页面</title> <link type="text/css" rel="stylesheet" href="../../static/css/style.css" /> <link rel="stylesheet" href="../../static/css/register.css" /> <style type="text/css"> .login_form { height: 420px; margin-top: 25px; } </style> <script type="text/javascript" src="../../static/script/jquery-1.7.2.js"></script> <script type="text/javascript" src="../../static/script/regist.js"></script> </head> <body> <div id="login_header"> <a href="../../index.html"> <img class="logo_img" alt="" src="../../static/img/logo.gif" /> </a> </div> <div class="login_banner"> <div class="register_form"> <h1>注册尚硅谷会员</h1> <form action="regist_success.html"> <div class="form-item"> <div> <label>用户名称:</label> <input id="username" type="text" placeholder="请输入用户名"/> </div> <span class="errMess" id="userErrMess">用户名、密码:只能是字母(大小写)、数字、_。6-18位</span> </div> <div class="form-item"> <div> <label>用户密码:</label> <input type="password" id="password" placeholder="请输入密码" /> </div> <span class="errMess" id="passErrMess">只能是字母(大小写)、数字、_。6-18位</span> </div> <div class="form-item"> <div> <label>确认密码:</label> <input type="password" id="rePassword" placeholder="请输入确认密码" /> </div> <span class="errMess" id="rePasswordErrMess">密码两次输入不一致</span> </div> <div class="form-item"> <div> <label>用户邮箱:</label> <input type="text" id="email" placeholder="请输入邮箱" /> </div> <span class="errMess" id="emailErrMess">请输入正确的邮箱格式</span> </div> <div class="form-item"> <div> <label>验证码:</label> <div class="verify"> <input type="text" id="verify" placeholder="" /> <img src="../../static/img/code.bmp" alt="" /> </div> </div> <span class="errMess" id="verifyErrMess">请输入正确的验证码</span> </div> <button class="btn" id="register">注册</button> </form> </div> </div> <div id="bottom"> <span> 尚硅谷书城.Copyright ©2015 </span> </div> </body> </html>
- 在
static/script/regist.js
文件中实现注册用户输入参数的校验$(function () { /** * 用户名校验 */ function checkUsername() { var reg = /^[a-zA-Z0-9_]{6,18}$/; var userVaule = $("#username").val(); if (reg.test(userVaule) == false) { $("#userErrMess").css("visibility", "visible"); return false; } else { $("#userErrMess").css("visibility", "hidden"); } } /** * 密码校验 */ function checkPassword() { var reg = /^[a-zA-Z0-9_]{6,18}$/; var passwordValue = $("#password").val(); if (reg.test(passwordValue) == false) { $("#passErrMess").css("visibility", "visible"); return false; } else { $("#passErrMess").css("visibility", "hidden"); } } /** * 确认密码 */ function checkrePassword() { var passwordValue = $("#password").val(); var rePasswordValue = $("#rePassword").val(); if (passwordValue != rePasswordValue) { $("#rePasswordErrMess").css("visibility", "visible"); return false; } else { $("#rePasswordErrMess").css("visibility", "hidden"); } } /** * 检查邮箱 */ function checkEmail(){ var reg = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/; var emailValue = $("#email").val(); if (reg.test(emailValue) == false){ $("#emailErrMess").css("visibility", "visible"); return false; }else { $("#emailErrMess").css("visibility", "hidden"); } } function checkVerify(){ var verifyValue = $("#verify").val(); if (verifyValue == ""){ $("#verifyErrMess").css("visibility", "visible"); return false; }else { $("#verifyErrMess").css("visibility", "hidden"); } } // 注册栏内容改变后校验 $("#username").change(checkUsername); $("#password").change(checkPassword); $("#rePassword").change(checkrePassword); $("#email").change(checkEmail); $("#verify").change(checkVerify); // 注册按钮后校验 $("#register").click(checkUsername); $("#register").click(checkPassword); $("#register").click(checkrePassword); $("#register").click(checkEmail); $("#register").click(checkVerify); })
三.阶段2:Servlet实战
1.需求:
实现用户的登录和注册功能。
- 登录成功重定向到登录成功页面,登录失败则转发到登录页面
- 注册成功重定向到注册成功页面,注册失败则转发到注册页面
2.原理:
使用三层模型来实现。
3.实现:
(0)项目依赖引入
- 引入Tomcat服务器
- 引入Servlet
第一步: RUN》Edit Configurations》
第二步:在当前项目的iml文件中引入tomcat
第三步:重启idea
第四步:引入Facets
(1)HTML页面
修改以下几个与登录注册相关的页面,①使用base标签完成绝对路径的修改;②点击登录按钮将用户名密码提交到LoginServlet中验证;③点击注册按钮将用户名、密码、邮箱提交到RegisterServlet中验证
- login.html
<!DOCTYPE html> <html> <head> <base href="http://localhost:8080/bookStoreTest1/"/> <meta charset="UTF-8" /> <title>尚硅谷会员登录页面</title> <link type="text/css" rel="stylesheet" href="static/css/style.css" /> <script type="text/javascript" src="static/script/jquery-1.7.2.js"></script> <script type="text/javascript" src="static/script/login.js"></script> </head> <body> <div id="login_header"> <a href="index.html"> <img class="logo_img" alt="" src="static/img/logo.gif" /> </a> </div> <div class="login_banner"> <div id="l_content"> <span class="login_word">欢迎登录</span> </div> <div id="content"> <div class="login_form"> <div class="login_box"> <div class="tit"> <h1>尚硅谷会员</h1> </div> <div class="msg_cont"> <b></b> <span class="errorMsg">请输入用户名和密码</span> </div> <div class="form"> <!--跳转到login对应的Servlet中--> <form action="login"> <label>用户名称:</label> <input class="itxt" type="text" placeholder="请输入用户名" autocomplete="off" tabindex="1" name="username" id="username" /> <br /> <br /> <label>用户密码:</label> <input class="itxt" type="password" placeholder="请输入密码" autocomplete="off" tabindex="1" name="password" id="password" /> <br /> <br /> <input type="submit" value="登录" id="sub_btn" /> </form> <div class="tit"> <a id = "submit" href="regist.html">立即注册</a> </div> </div> </div> </div> </div> </div> <div id="bottom"> <span> 尚硅谷书城.Copyright ©2015 </span> </div> </body> </html>
- login_success.html
<!DOCTYPE html> <html> <head> <base href="http://localhost:8080/bookStoreTest1/"/> <meta charset="UTF-8"> <title>尚硅谷会员注册页面</title> <link type="text/css" rel="stylesheet" href="static/css/style.css" > <style type="text/css"> h1 { text-align: center; margin-top: 200px; } h1 a { color:red; } </style> </head> <body> <div id="header"> <a href="index.html"> <img class="logo_img" alt="" src="static/img/logo.gif" /> </a> <div> <span>欢迎<span class="um_span">张总</span>光临尚硅谷书城</span> <a href="pages/order/order.html">我的订单</a> <a href="index.html">注销</a> <a href="index.html">返回</a> </div> </div> <div id="main"> <h1>欢迎回来 <a href="index.html">转到主页</a></h1> </div> <div id="bottom"> <span> 尚硅谷书城.Copyright ©2015 </span> </div> </body> </html>
- register.html
<!DOCTYPE html> <html> <head> <base href="http://localhost:8080/bookStoreTest1/"/> <meta charset="UTF-8" /> <title>尚硅谷会员注册页面</title> <link type="text/css" rel="stylesheet" href="static/css/style.css" /> <link rel="stylesheet" href="static/css/register.css" /> <style type="text/css"> .login_form { height: 420px; margin-top: 25px; } </style> <script type="text/javascript" src="static/script/jquery-1.7.2.js"></script> <script type="text/javascript" src="static/script/regist.js"></script> </head> <body> <div id="login_header"> <a href="index.html"> <img class="logo_img" alt="" src="static/img/logo.gif" /> </a> </div> <div class="login_banner"> <div class="register_form"> <h1>注册尚硅谷会员</h1> <!--跳转到register对应的Servlet--> <form action="register"> <div class="form-item"> <div> <label>用户名称:</label> <input id="username" type="text" name="username" placeholder="请输入用户名"/> </div> <span class="errMess" id="userErrMess">用户名、密码:只能是字母(大小写)、数字、_。6-18位</span> </div> <div class="form-item"> <div> <label>用户密码:</label> <input type="password" id="password" name="password" placeholder="请输入密码" /> </div> <span class="errMess" id="passErrMess">只能是字母(大小写)、数字、_。6-18位</span> </div> <div class="form-item"> <div> <label>确认密码:</label> <input type="password" id="rePassword" name="rePassword" placeholder="请输入确认密码" /> </div> <span class="errMess" id="rePasswordErrMess">密码两次输入不一致</span> </div> <div class="form-item"> <div> <label>用户邮箱:</label> <input type="text" id="email" name="email" placeholder="请输入邮箱" /> </div> <span class="errMess" id="emailErrMess">请输入正确的邮箱格式</span> </div> <div class="form-item"> <div> <label>验证码:</label> <div class="verify"> <input type="text" id="verify" placeholder="" /> <img src="static/img/code.bmp" alt="" /> </div> </div> <span class="errMess" id="verifyErrMess">请输入正确的验证码</span> </div> <button class="btn" id="register">注册</button> </form> </div> </div> <div id="bottom"> <span> 尚硅谷书城.Copyright ©2015 </span> </div> </body> </html>
- register_success.html
<!DOCTYPE html> <html> <head> <base href="http://localhost:8080/bookStoreTest1/"/> <meta charset="UTF-8"> <title>尚硅谷会员注册页面</title> <link type="text/css" rel="stylesheet" href="static/css/style.css" > <style type="text/css"> h1 { text-align: center; margin-top: 200px; } h1 a { color:red; } </style> </head> <body> <div id="header"> <a href="index.html"> <img class="logo_img" alt="" src="static/img/logo.gif" /> </a> <span class="wel_word"></span> <div> <span>欢迎<span class="um_span">张总</span>光临尚硅谷书城</span> <a href="pages/order/order.html">我的订单</a> <a href="index.html">注销</a> <a href="index.html">返回</a> </div> </div> <div id="main"> <h1>注册成功! <a href="index.html">转到主页</a></h1> </div> <div id="bottom"> <span> 尚硅谷书城.Copyright ©2015 </span> </div> </body> </html>
(2)bean
在src目录下创建com.bookstore.bean
目录,用于存放数据库的模型类,并创建User类。
package com.bookstore.bean;
/**
* 用户类
*/
public class User {
private Integer id; // 推荐使用包装类,更利于类型转化
private String username;
private String password;
private String email;
public User(Integer id, String username, String password, String email) {
this.id = id;
this.username = username;
this.password = password;
this.email = email;
}
public User() {
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", email='" + email + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
(3)Dao
在Dao层我们应该将对数据库的操作封装好。
(创建如下目录:
(导入jdbc相关的第三方软件
(在utils目录下,创建文件JDBCUtils .java
用于封装数据库的连接,释放
package com.bookstore.utils;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
/**
* 获取连接和释放连接的工具类
* @author Chunsheng Zhang
*
*/
public class JDBCUtils {
private static DataSource dataSource;
static {
try {
//1、读取druip.properties文件
Properties pro = new Properties();
pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
//2、连接连接池
dataSource = DruidDataSourceFactory.createDataSource(pro);
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() {
Connection connection = null;
try {
connection = dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
//释放连接
public static void releaseConnection(Connection connection) {
if(connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
(在dao目录下创建如下文件:
- BaseDao.java
package com.bookstore.dao; import com.bookstore.utils.JDBCUtils; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.apache.commons.dbutils.handlers.ScalarHandler; import java.sql.Connection; import java.sql.SQLException; import java.util.List; /** * 定义一个用来被继承的对数据库进行基本操作的Dao * * @param <T> * @author Chunsheng Zhang */ public class BaseDao<T> { private QueryRunner queryRunner = new QueryRunner(); public BaseDao() { } /** * 通用的增删改操作 * sql: insert delete update * * @param sql * @param params * @return */ public int update(String sql, Object... params) { // 获取连接 Connection connection = JDBCUtils.getConnection(); int count = 0; try { count = queryRunner.update(connection, sql, params); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtils.releaseConnection(connection); } return count; } /** * 获取一个对象 * * @param sql * @param params * @return */ public T getBean(Class<T> clazz, String sql, Object... params) { // 获取连接 Connection connection = JDBCUtils.getConnection(); T t = null; try { t = queryRunner.query(connection, sql, new BeanHandler<T>(clazz), params); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtils.releaseConnection(connection); } return t; } /** * 获取所有对象 * * @param sql * @param params * @return */ public List<T> getBeanList(Class<T> clazz, String sql, Object... params) { // 获取连接 Connection connection = JDBCUtils.getConnection(); List<T> list = null; try { list = queryRunner.query(connection, sql, new BeanListHandler<T>( clazz), params); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtils.releaseConnection(connection); } return list; } /** * 获取单个数值的通用方法 */ public Object getSingleValue(String sql, Object... params) { // 获取连接 Connection connection = JDBCUtils.getConnection(); Object o = null; try { o = queryRunner.query(connection, sql, new ScalarHandler<>(), params); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtils.releaseConnection(connection); } return o; } }
- UserDao接口
package com.bookstore.dao; import com.bookstore.bean.User; import java.util.List; /** * * sql: SELECT * FROM users WHERE(username="?" AND password="?"); */ public interface UserDao { /** * 根据用户名密码查询单个用户。sql: SELECT * FROM users WHERE(username="?" AND password="?"); * @param user: 当sql中有多个参数需要赋值时,推荐传入bean对象 * @return */ public User getUserByUsernamePwd(User user); /** * 根据用户名查询多个用户。sql: SELECT * FROM users WHERE(username="?"); * @param username: 当sql中只有一个参数值需要赋值时,可以不用封装为对象 * @return */ public List<User> getUserByUsername(String username); /** * 将User对象储存到数据库中。sql=“INSERT INTO users(username,`password`,email) VALUES(?,?,?);” * @param user * @return */ public int saveUser(User user); }
- UserDaoImpl.java
package com.bookstore.dao.impl; import com.bookstore.bean.User; import com.bookstore.dao.BaseDao; import com.bookstore.dao.UserDao; import java.util.List; public class UserDaoImll extends BaseDao<User> implements UserDao { /** * 根据用户名密码查询单个用户 * * @param user: 当sql中有多个参数需要赋值时,推荐传入bean对象 * @return */ @Override public User getUserByUsernamePwd(User user) { String sql = "SELECT * FROM users WHERE(username=? AND password=?)"; return getBean(User.class, sql, user.getUsername(), user.getPassword()); } /** * 根据用户名查询多个用户 * * @param username * @return */ @Override public List<User> getUserByUsername(String username) { String sql = "SELECT * FROM users WHERE(username=?)"; return getBeanList(User.class, sql, username); } /** * 储存User对象到数据库中 * * @param user * @return */ @Override public int saveUser(User user) { String sql = "INSERT INTO users(username,`password`,email) VALUES(?,?,?)"; return update(sql, user.getUsername(), user.getPassword(), user.getEmail()); } }
(4)service
在service目录下可以封装业务逻辑的代码
- UserServices接口
package com.bookstore.service; import com.bookstore.bean.User; /** * 处理用户相关业务逻辑 */ public interface UserServices { /** * 处理用户登录相关业务。 * * @param user */ User login(User user); /** * 处理用户注册的方法 * * @param user * @return */ boolean regist(User user); }
- UserServicesImpl.java
package com.bookstore.service.impl; import com.bookstore.bean.User; import com.bookstore.dao.impl.UserDaoImll; import com.bookstore.service.UserServices; import java.util.List; public class UserservicesImpl extends UserDaoImll implements UserServices { /** * 处理用户登录业务逻辑 * @param user * @return */ @Override public User login(User user) { User userRes = getUserByUsernamePwd(user); if (userRes == null){ return null; }else { return userRes; } } @Override public boolean regist(User user) { List<User> users = getUserByUsername(user.getUsername()); if (users.size() > 0){ return false; }else { int i = saveUser(user); if (i>=1){ return true; } return false; } } }
(5)Servlet
- LoginServlet.java
package com.bookstore.servlet; import com.bookstore.bean.User; import com.bookstore.service.UserServices; import com.bookstore.service.impl.UserservicesImpl; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet(name = "LoginServlet", value = "/login") public class LoginServlet extends HttpServlet { private UserServices userservices = new UserservicesImpl(); @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取用户名,密码 String username = request.getParameter("username"); String password = request.getParameter("password"); // 检查用户名密码是否正确 User userOld = new User(); userOld.setUsername(username); userOld.setPassword(password); User loginUser = userservices.login(userOld); if (loginUser != null) { // 用户名密码正确 response.sendRedirect("/bookStoreTest1/pages/user/login_success.html"); } else { // 用户名密码不正确 request.getRequestDispatcher("/pages/user/login.html").forward(request, response); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
- RegisterServlet.java\
package com.bookstore.servlet; import com.bookstore.bean.User; import com.bookstore.service.impl.UserservicesImpl; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet(name = "RegisteServlet", value = "/register") public class RegisteServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); String email = request.getParameter("email"); User user = new User(null,username,password,email); UserservicesImpl userservices = new UserservicesImpl(); boolean registFag = userservices.regist(user); if (registFag){ response.sendRedirect("/bookStoreTest1/pages/user/regist_success.html"); }else { request.getRequestDispatcher("/pages/user/regist.html").forward(request,response); } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } }
4.原理讲解
想一想为什么不在Servlet中直接调用dao进行业务处理呢?
- 为了解耦,因为业务逻辑层是会经常变动的。将其提取出来更加便于后期的维护
- 而且某些业务逻辑会在多个Servlet中使用,提取出来也能实现复用