书城项目页面原型可以直接从gitee上下载:https://gitee.com/ouyi19940129/BookStore.git
先创建一个普通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中使用,提取出来也能实现复用