# BookShop
**Repository Path**: fowner/bookshop
## Basic Information
- **Project Name**: BookShop
- **Description**: 通过运用JavaWeb三大组件组件之servlet,Filter进行JavaWeb项目开发。
- **Primary Language**: Java
- **License**: GPL-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 65
- **Forks**: 6
- **Created**: 2020-11-12
- **Last Updated**: 2025-08-20
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 书城项目
## 概要
```
该项目主要实现了用户的注册和登录功能。
通过使用Servlet,JavaEE三层(Web,Service,Dao层),以及Web关联的一些基础知识进行项目的开发。
项目中还涉及到一些常用的工具类:
例如text/html
数据库连接池工具:druid
数据库操作工具:commons-dbutils
```
## 基本环境说明
+ Maven 3.6.1(jar管理工具)
+ Tomcat 8.5.59(服务器)
+ JDK 1.8
+ JavaEE 8.0
+ MySql 5.7.29(数据库管理系统)
+ IDEA 2019免费版(开发工具)
+ druid 1.2.3(数据库连接池)
+ commons-dbutils 1.7 (数据库操作工具)
+ kaptcha 2.3.2(验证码)
+ Gson 2.8.6(Json支持)
注:所有依赖参考pom.xml
## 构建静态网页
+ 新建Maven项目webapp模型
+ 把静态网页粘贴到webapp目录下
+ pages文件夹
+ static文件夹
+ index.html文件
+ web.xml中配置默认启动画面
```xml
index.jsp
index.html
index.htm
```
+ 确认静态页面的联动
注:注册的验证已经完成
## 实现用户注册和登录功能
### 创建src目录
+ web层
com.dream.servlet
+ service层
+ service接口包
com.dream.service
+ service接口实现包
com.dream.service.impl
+ dao层
+ dao接口包
com.dream.dao
+ dao接口实现类包
com.dream.dao.impl
+ 实体对象
com.dream.bean
+ 工具包
com.dream.utils
+ 测试包(使用Maven的测试文件夹)
test
### 编码的流程
+ 创建书城的数据库和表结构并把admin数据创建好
```mysql-sql
//创建字符集为utf-8的BookShop数据库
CREATE SCHEMA `BookShop` DEFAULT CHARACTER SET utf8;
//创建用户表
create table `BookShop`.t_user(
`id` int primary key auto_increment,
`username` varchar(20) not null unique,
`password` varchar(32) not null,
`email` varchar(200),
`registtime` date not null,
`updatetime` varchar(255)
);
//插入管理员的数据
insert into t_user(`username`,`password`,`email`,`registtime`) values ('admin','admin','admin@test.com',current_date);
//查询插入后结果
select * from t_user;
```
+ 创建与数据库表对应的JavaBean对象
```java
package com.dream.bean;
/**
* @author 匠人码农
* @date 2020/11/11 8:19
* 概要:
* 用户信息类
*/
public class User {
//ID
private Integer id;
//用户名
private String userName;
//密码
private String password;
//邮件地址
private String email;
//创建时间
private String registTime;
//更新时间
private String updateTime;
//无参构造器
public User() {
}
//有参数构造器
public User(Integer id, String userName, String password, String email, String registTime, String updateTime) {
this.id = id;
this.userName = userName;
this.password = password;
this.email = email;
this.registTime = registTime;
this.updateTime = updateTime;
}
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;
}
public String getRegistTime() {
return registTime;
}
public void setRegistTime(String registTime) {
this.registTime = registTime;
}
public String getUpdateTime() {
return updateTime;
}
public void setUpdateTime(String updateTime) {
this.updateTime = updateTime;
}
}
```
+ 编写工具类JdbcUtil
+ 需要的jar包依赖
```xml
mysql
mysql-connector-java
5.1.47
com.alibaba
druid
1.2.3
junit
junit
4.11
test
```
+ 创建jdbc.properties属性配置文件
```properties
#用户名
username=root
#密码
password=admin2020
#数据库的url地址
url=jdbc:mysql://localhost:3306/BookShop
#jdbc驱动
driverClassName=com.mysql.jdbc.Driver
#连接池初始连接初始个数
initialZize=5
#连接池最大连接数
maxActive=10
```
+ 编写JdbcUtils工具类
```java
package com.dream.utils;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
/**
* @author 匠人码农
* @date 2020/11/11 8:40
* 概要:
* jdbc工具类
*/
public class JdbcUtils {
//数据库连接池
public static DruidDataSource dataSource;
/*
* 创建数据库连接池静态代码块
*/
static {
try {
//创建properti对象
Properties properties = new Properties();
//获取jsbc配置文件数据流
InputStream inputSteam = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
//导入jdbc配置文件
properties.load(inputSteam);
//创建数据库连接池
dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取数据库连接池中连接
*/
/**
* 获取数据库连接池中连接
* @return 如果不为null,则获取数据库连接成功.
* 如果为null,则获取数据库连接失败.
*/
public static Connection getConnection(){
Connection conn = null;
try {
conn = dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
/**
* 关闭数据库连接
*/
public static void close(Connection conn){
//连接不为null的话,关闭连接。
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
```
+ 工具类JdbcUtils测试
```java
package com.dream.utils;
import org.junit.Test;
import java.sql.Connection;
/**
* @author 匠人码农
* @date 2020/11/11 10:18
* 概要:
* JdbcUtils测试类
*/
public class JdbcUtilsTest {
@Test
public void testJdbcUtils() {
for(int i = 0;i < 20 ;i++){
//获取连接
Connection conn = JdbcUtils.getConnection();
//打印连接
System.out.println(conn);
//关闭连接
JdbcUtils.close(conn);
}
}
}
```
+ 编写BaseDao
+ 导入sql操作工具包
```xml
commons-dbutils
commons-dbutils
1.7
```
+ 创建BaseDao.java类
```java
package com.dream.dao.impl;
import com.dream.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;
/**
* @author 匠人码农
* @date 2020/11/11 10:55
* 概要:
* BaseDao类
*
*/
public abstract class BaseDao {
//使用apache的DbUtils操作数据库
private final QueryRunner queryRunner = new QueryRunner();
/**
* 用来执行insert,update,delete语句
* @param sql 要执行的sql文
* @param args sql的参数
* @return 如果查询到结果返回>1的值.
* 返回-1 表示没有查询到结果。
*/
public int update(String sql,Object ... args){
//获取连接
Connection conn = JdbcUtils.getConnection();
//执行sql
try {
return queryRunner.update(conn,sql,args);
} catch (SQLException e) {
e.printStackTrace();
} finally {
//关闭连接
JdbcUtils.close(conn);
}
return -1;
}
/**
* 查询返回一个JavaBean的sql
* @param type JavaBean类型
* @param sql 执行的sql文
* @param args sql的参数
* @param 类型的泛型
* @return 返回一个T类型的对象
*/
public T queryForOne(Class type,String sql,Object ... args){
//获取连接
Connection conn = JdbcUtils.getConnection();
//执行sql
try {
return queryRunner.query(conn,sql,new BeanHandler(type),args);
} catch (SQLException e) {
e.printStackTrace();
} finally {
//关闭连接
JdbcUtils.close(conn);
}
return null;
}
/**
* 返回一个多个JavaBean的List结果集合
* @param type JavaBean类型
* @param sql 执行的sql文
* @param args sql的参数
* @param 类型的泛型
* @return 返回一个List
*/
public List queryForList(Class type,String sql,Object ... args){
//获取连接
Connection conn = JdbcUtils.getConnection();
//执行sql
try {
return queryRunner.query(conn,sql,new BeanListHandler(type),args);
} catch (SQLException e) {
e.printStackTrace();
} finally {
//关闭连接
JdbcUtils.close(conn);
}
return null;
}
/**
* 返回一个一行一列的结果
* @param sql 查询的sql
* @param args sql参数
* @return 返回一个一行一列的结果
*/
public Object queryForSingleValue(String sql,Object ... args){
//获取连接
Connection conn = JdbcUtils.getConnection();
//执行sql
try {
return queryRunner.query(conn,sql,new ScalarHandler(),args);
} catch (Exception e) {
e.printStackTrace();
}finally {
JdbcUtils.close(conn);
}
return null;
}
}
```
+ 编写UserDao和测试
+ 创建UserDao接口类
```java
package com.dream.dao;
import com.dream.bean.User;
/**
* @author 匠人码农
* @date 2020/11/11 13:34
* 概要:
* UserDao接口类
*/
public interface UserDao {
/**
* 根据用户名查询用户信息
* @param userName 用户名
* @return 如果为null则用户不存在,否则结果为查询的用户信息。
*/
User queryUserByUserName(String userName);
/**
* 根据用户名和密码查询用户信息
* @param userName 用户名
* @param password 密码
* @return 如果为null则用户名不存在或者密码错误,否则该用户存在。
*/
User queryUserByUserNameAndPassword(String userName,String password);
/**
* 保存用户信息
* @param user 用户信息
* @return 如果为-1,保存失败。否则保存成功。
*/
int saveUser(User user);
}
```
+ 创建USerDao接口实现类
```java
package com.dream.dao.impl;
import com.dream.bean.User;
import com.dream.dao.UserDao;
/**
* @author 匠人码农
* @date 2020/11/11 13:43
* 概要:
* UserDao接口的实现类
*/
public class UserDaoImpl extends BaseDao implements UserDao {
@Override
public User queryUserByUserName(String userName) {
String sql = "select `id`,`username`,`password`,`email` from t_user where username = ?";
return queryForOne(User.class,sql,userName);
}
@Override
public User queryUserByUserNameAndPassword(String userName, String password) {
String sql = "select `id`,`username`,`password`,`email` from t_user where username = ? and password = ?";
return queryForOne(User.class,sql,userName,password);
}
@Override
public int saveUser(User user) {
String sql = "insert into t_user(`username`,`password`,`email`,`registtime`) values(?,?,?,?)";
return update(sql,user.getUserName(),user.getPassword(),user.getEmail(),user.getRegistTime());
}
}
```
+ UserDao测试类
```java
package com.dream.dao;
import com.dream.bean.User;
import com.dream.dao.impl.UserDaoImpl;
import org.junit.Test;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author 匠人码农
* @date 2020/11/11 14:08
* 概要:
* UserDao测试类
*/
public class UserDaoTest {
@Test
public void queryUserByUserName() {
UserDao userDao = new UserDaoImpl();
if(userDao.queryUserByUserName("admin") != null){
System.out.println("admin用户存在!");
}else{
System.out.println("admin用户不存在!");
}
if(userDao.queryUserByUserName("gust") != null){
System.out.println("gust用户存在!");
}else{
System.out.println("gust用户不存在!");
}
}
@Test
public void queryUserByUserNameAndPassword() {
UserDao userDao = new UserDaoImpl();
if(userDao.queryUserByUserNameAndPassword("admin","admin") != null){
System.out.println("登录成功");
}else{
System.out.println("用户名或者密码错误!");
}
if(userDao.queryUserByUserNameAndPassword("admin","123456") != null){
System.out.println("登录成功");
}else{
System.out.println("用户名或者密码错误!");
}
}
@Test
public void saveUser() {
User user = new User();
user.setUserName("gust");
user.setPassword("gust");
user.setEmail("gust@test.com");
Date date = new Date();
SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
user.setRegistTime(dateFormat.format(date.getTime()));
UserDao userDao = new UserDaoImpl();
if(userDao.queryUserByUserName(user.getUserName()) != null){
System.out.println("用户已经被注册,请更换用户名!");
}else {
if (-1 != userDao.saveUser(user)) {
System.out.println("用户注册成功!");
} else {
System.out.println("用户注册失败!");
}
}
}
}
```
+ UserService层
+ UserService接口
```java
package com.dream.service;
import com.dream.bean.User;
/**
* @author 匠人码农
* @date 2020/11/11 16:27
* 概要:
* 用户接口
*/
public interface UserService {
/**
* 注册用户功能
* @param user
*/
void registUser(User user);
/**
* 登录
* @param user
* @return
*/
User login(User user);
/**
* 检查用户是否已经存在
* @param userName
* @return true:表示用户已经存在
* false:表示用户不存在
*
*/
boolean existsUserName(String userName);
}
```
+ UserService接口实现类
```java
package com.dream.service.impl;
import com.dream.bean.User;
import com.dream.dao.UserDao;
import com.dream.dao.impl.UserDaoImpl;
import com.dream.service.UserService;
/**
* @author 匠人码农
* @date 2020/11/11 16:33
* 概要:
* 业务处理service
*/
public class UserServiceImpl implements UserService {
//UserDao
UserDao userDao = new UserDaoImpl();
@Override
public void registUser(User user) {
userDao.saveUser(user);
}
@Override
public User login(User user) {
return userDao.queryUserByUserNameAndPassword(user.getUserName(),user.getPassword());
}
@Override
public boolean existsUserName(String userName) {
if(null != userDao.queryUserByUserName(userName)){
return true;
}
return false;
}
}
```
+ 实现注册功能
+ 创建RegsitServlet.java
```java
package com.dream.servlet;
import com.dream.bean.User;
import com.dream.service.UserService;
import com.dream.service.impl.UserServiceImpl;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author 匠人码农
* @date 2020/11/11 17:11
* 概要:
* 注册用户功能
*/
public class RegistServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
User user = new User();
UserService userService = new UserServiceImpl();
//获取请求参数
//用户名
String userName = req.getParameter("username");
//密码
String password = req.getParameter("password");
//邮件地址
String email = req.getParameter("email");
//验证码
String code = req.getParameter("code");
//检查验证码
if(!"6n6np".equals(code)){
//跳转回登录界面
req.getRequestDispatcher("/pages/user/regist.html").forward(req,resp);
} else {
//bean设定
user.setUserName(userName);
user.setPassword(password);
user.setEmail(password);
user.setRegistTime(new SimpleDateFormat("yyyy/MM/dd hh:mm:ss").format(new Date()));
//检查用户名是否存在
//已经存在
if(userService.existsUserName(userName)){
//跳转回登录页面
req.getRequestDispatcher("/pages/user/regist.html").forward(req,resp);
//不存在
} else {
//跳转到成功页面
userService.registUser(user);
req.getRequestDispatcher("/pages/user/regist_success.html").forward(req,resp);
}
}
}
}
```
+ 在Web.xml中配置RegistServlet
```xml
RegistServlet
com.dream.servlet.RegistServlet
RegistServlet
/registServlet
```
+ 修改regist.html的表单action和method方法
```html