1.项目简介

书城项目采用MVC设计模式,软件三层架构。
①表现层:接受用户的请求,调用业务逻辑层处理用户请求,显示处理结果。对应着View视图(jsp)与Controller控制器(servlet实现)。
②业务逻辑层:调用数据访问层处理业务逻辑,采用面向接口编程思想,先定义接口,在创建实现类。
③数据访问层: 用来操作数据库,对数据库进行增删改查。采用面向接口编程的思想,先定义接口,再创建实现类。②和③加上实体类模型对应着Model模型,负责各个功能的实现。
采用三层架构可以明显降低耦合度,便于维护以及扩展开发;但是也降低了系统的性能,以及增加了代码量。
本项目实现了用户通过浏览器访问以及注册或者登录书城的功能,用户可以在书城中浏览图书,添加购物车以及提交订单等操作,管理员可以对书城的图书进行增删改查等操作。
本项目采用MySQL数据库进行数据管理以及数据库表的设计。

部分界面如下:
主界面:

登录界面:如果输入错误,用户信息回显到输入框,并提示用户。

注册界面:输入用户名后,会有相应的提示。

登陆成功,session域中保存了用户信息,显示到界面。添加购物车后,界面会有提示信息

购物车:

2.根据需求分阶段实现项目

在项目的开始阶段,我们需要创建项目需要的数据库:
这是用户表:

CREATE DATABASE book;
CREATE TABLE t_user(id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(100) NOT NULL UNIQUE,
`password` VARCHAR(32) NOT NULL,
email VARCHAR(200));

这是书籍表:

CREATE TABLE t_book(id INT PRIMARY KEY AUTO_INCREMENT,`name` VARCHAR(100),price DECIMAL(11,2),author VARCHAR(100),sales INT,stock INT,img_path VARCHAR(200));

这是订单表以及订单项表:

CREATE TABLE t_order(order_id VARCHAR(50) PRIMARY KEY,create_time DATETIME,price DECIMAL(11,2),`status` INT,user_id INT,FOREIGN KEY(user_id) REFERENCES t_user(id));CREATE TABLE t_order_item(id INT PRIMARY KEY AUTO_INCREMENT,`name` VARCHAR(100),`count` INT,price DECIMAL(11,2),`total_price` DECIMAL(11,2),order_id VARCHAR(50),FOREIGN KEY(order_id) REFERENCES t_order(order_id)
);

然后就是创建包,项目结构如下:

第一阶段:表单验证
例如项目要求密码必须由字母,数字,下划线组成,并且长度为5到12位。

 // 验证密码:必须由字母,数字下划线组成,并且长度为5到12位//1 获取用户名输入框里的内容var passwordText = $("#password").val();//2 创建正则表达式对象var passwordPatt = /^\w{5,12}$/;//3 使用test方法验证if (!passwordPatt.test(passwordText)) {//4 提示用户结果$("span.errorMsg").text("密码不合法!");return false;}

第二阶段:实现用户的注册和登录

我们已经创建好了用户表,根据用户表在pojo包里创建javaBean实例:
public class User {private int id;private String username;private String password;private String email;

并创建构造器,get/set等方法。
进行分层编写,dao层进行与数据库交互,service层处理业务逻辑并调用dao层方法:

public interface UserDao {/*** 根据用户名查询用户信息** @param username* @return 如果返回null则说明没有查到*/public User queryUsername(String username);/*** 根据用户名和密码查询** @param username* @param password* @return null 表示没有查到*/public User queryUserByUsernameAndPassword(String username, String password);/*** 保存用户信息** @return*/public int saveUser(User user);
}

编写实现类,实现该接口:

public class UserDaoImpl extends BaseDao implements UserDao {@Overridepublic User queryUsername(String username) {String sql = "select id,username,password,email from t_user where username = ?";return queryForOne(User.class,sql,username);}@Overridepublic 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);}@Overridepublic int saveUser(User user) {String sql = "insert into t_user(username,password,email) values (?,?,?)";return update(sql,user.getUsername(),user.getPassword(),user.getEmail());}
}

service层里接口和实现类如下:

package com.atguigu.service;import com.atguigu.pojo.User;/*** @author: SunXiaolin* @create: 2021-04-13-12:03*/
public interface UserService {/*** 注册用户* @param user*/public void registerUser(User user);/*** 登录* @param user* @return 如果返回null说明登录失败*/public User login(User user);/*** 检查用户名是否可用* @param username* @return 返回true表示用户名已存在*/public boolean existUsername(String username);}

实现类:

package com.atguigu.service.impl;import com.atguigu.dao.UserDao;
import com.atguigu.dao.impl.UserDaoImpl;
import com.atguigu.pojo.User;
import com.atguigu.service.UserService;/*** @author: SunXiaolin* @create: 2021-04-13-12:24*/
public class UserServiceImpl implements UserService {private UserDao userDao = new UserDaoImpl();@Overridepublic void registerUser(User user) {userDao.saveUser(user);}@Overridepublic User login(User user) {return userDao.queryUserByUsernameAndPassword(user.getUsername(),user.getPassword());}@Overridepublic boolean existUsername(String username) {if (userDao.queryUsername(username) == null){//等于null说明没有查到,表示可用return false;}else{return true;}}
}

接下来就可以编写web层了:这里form表单跳转到userServlet程序,并发送了一个隐藏的action,值为register,从而调用servlet程序的注册方法

 <form action="userServlet" method="post"><input type="hidden" name="action" value="register"/><label>用户名称:</label><input class="itxt" type="text" placeholder="请输入用户名"value="${requestScope.username}"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/><label>确认密码:</label><input class="itxt" type="password" placeholder="确认密码"autocomplete="off" tabindex="1" name="repwd" id="repwd"/><br/><br/><label>电子邮件:</label><input class="itxt" type="text" placeholder="请输入邮箱地址"value="${requestScope.email}"autocomplete="off" tabindex="1" name="email" id="email"/><br/><br/><label>验证码:</label><input class="itxt" type="text" name="code" style="width: 80px;" id="code"/><img id="code_img" alt="" src="kaptcha.jpg" style="float: right; margin-right: 40px;width:110px;height: 30px;
"><br/><br/><input type="submit" value="注册" id="sub_btn"/></form>

进入到servlet程序后,如下:不符合要求的返回注册页面,通过验证则调用service层方法,进而调用dao方法,从而将用户信息保存到数据库。

protected void register(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取Session中的验证码String token = (String) req.getSession().getAttribute(KAPTCHA_SESSION_KEY);//删除Session中的验证码,防止复用req.getSession().removeAttribute(KAPTCHA_SESSION_KEY);//1.获取请求的参数String username = req.getParameter("username");String password = req.getParameter("password");String email = req.getParameter("email");String code = req.getParameter("code");System.out.println(666);User user = WebUtils.copyParamToBean(req.getParameterMap(),new User());//2.检查验证码是否正确   if (token != null && token.equalsIgnoreCase(code)) {if (userService.existUsername(username)) {req.setAttribute("msg", "用户名已存在");req.setAttribute("username", username);req.setAttribute("email", email);req.getRequestDispatcher("pages/user/regist.jsp").forward(req, resp);} else {userService.registerUser(new User(username, password, email));req.getRequestDispatcher("pages/user/regist_success.jsp").forward(req, resp);}} else {//把回显信息,保存到request域中req.setAttribute("msg", "验证码不正确");req.setAttribute("username", username);req.setAttribute("email", email);//验证码不正确req.getRequestDispatcher("pages/user/regist.jsp").forward(req, resp);}

关于图书模块,大体和如上思路一样。
如下是bookservlet程序:

package com.atguigu.web;import com.atguigu.pojo.Book;
import com.atguigu.pojo.Page;
import com.atguigu.service.BookService;
import com.atguigu.service.impl.BookServiceImpl;
import com.atguigu.utils.WebUtils;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;/*** @author: SunXiaolin* @create: 2021-04-18-13:04*/
public class BookServlet extends BaseServlet {BookService bookService = new BookServiceImpl();protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {int pageNo = WebUtils.parseInt(req.getParameter("pageNo"),0);pageNo += 1;//1.获取请求的参数,封装成book对象Book book = WebUtils.copyParamToBean(req.getParameterMap(),new Book());//2.调用BookService.addBook()保存图书bookService.addBook(book);//3.跳到图书列表页面 /manager/bookServlet?action=list//重定向resp.sendRedirect(req.getContextPath()+"/manager/bookServlet?action=page&pageNo=" + pageNo);}protected void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.获取请求参数,封装成Book对象Book book = WebUtils.copyParamToBean(req.getParameterMap(), new Book());//2.调用BookService.updateBook方法,修改图书bookService.updateBook(book);//3.重定向回图书列表管理页面resp.sendRedirect(req.getContextPath()+"/manager/bookServlet?action=page&pageNo=" + req.getParameter("pageNo"));}protected void getBook(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.获取请求的参数图书编号int id = WebUtils.parseInt(req.getParameter("id"),0);//2.调用bookService.queryBookById()查询图书Book book = bookService.queryBookById(id);//3.保存到request域中req.setAttribute("book",book);//4.请求转发到pages/manager/book_edit.jspreq.getRequestDispatcher("/pages/manager/book_edit.jsp").forward(req,resp);}protected void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.获取请求的参数id,图书编号int id = WebUtils.parseInt(req.getParameter("id"),0);//2.调用bookService.deleteBookById方法。删除图书bookService.deleteBookById(id);//3.重定向图书列表管理页面 /book/manager/bookServlet?action=listresp.sendRedirect(req.getContextPath()+"/manager/bookServlet?action=page&pageNo=" + req.getParameter("pageNo"));}protected void list(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.通过bookService查询全部图书List<Book> books = bookService.queryBooks();//2.把全部图书保存到request域中req.setAttribute("books",books);//3.请求转发到/pages/manager/book_manager.jsp页面req.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(req,resp);}/*** 处理分页功能* @param req* @param resp* @throws ServletException* @throws IOException*/protected void page(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.获取请求的参数pageNo、pageSizeint pageNo = WebUtils.parseInt(req.getParameter("pageNo"),1);int pageSize = WebUtils.parseInt(req.getParameter("pageSize"), Page.PAGE_SIZE);//2.调用BookService.page(pageNo,pageSize) page对象Page<Book> page = bookService.page(pageNo,pageSize);page.setUrl("manager/bookServlet?action=page");//3.保存page对象到request域中req.setAttribute("page",page);//4.请求转发到pages/manager/book_manager.jsp页面req.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(req,resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {super.doPost(req,resp);}}

购物车部分采用的是session实现,把购物车信息保存到session域中:

 protected void addItem(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 获取请求的参数 商品编号int id = WebUtils.parseInt(req.getParameter("id"), 0);// 调用 bookService.queryBookById(id):Book 得到图书的信息Book book = bookService.queryBookById(id);// 把图书信息,转换成为 CartItem 商品项CartItem cartItem = new CartItem(book.getId(), book.getName(), 1, book.getPrice(), book.getPrice());// 调用 Cart.addItem(CartItem);添加商品项Cart cart = (Cart) req.getSession().getAttribute("cart");//        System.out.println(req.getSession().isNew());if (cart == null) {cart = new Cart();}req.getSession().setAttribute("cart", cart);cart.addItem(cartItem);//        System.out.println(cart);
//        System.out.println("请求头 Referer 的值:" + req.getHeader("Referer"));// 重定向回原来商品所在的地址页面resp.sendRedirect(req.getHeader("Referer"));//最后一个添加的名称req.getSession().setAttribute("lastName", cartItem.getName());}

关于订单模块思路介绍:

根据上图逐步实现各个方法。servlet部分如下:

package com.atguigu.web;import com.atguigu.pojo.Cart;
import com.atguigu.pojo.Order;
import com.atguigu.pojo.OrderItem;
import com.atguigu.pojo.User;
import com.atguigu.service.OrderService;
import com.atguigu.service.impl.OrderServiceImpl;
import com.atguigu.utils.JDBCUtils;
import com.atguigu.utils.WebUtils;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;/*** @author: SunXiaolin* @create: 2021-04-28-21:48*/
public class OrderServlet extends BaseServlet {//创建service实例OrderService orderService = new OrderServiceImpl();//删除所有订单protected void deleteOrders(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String orderId = WebUtils.parseString(req.getParameter("orderId"));orderService.deleteOrder(orderId);resp.sendRedirect(req.getContextPath()+"/orderServlet?action=showMyOrders");}//删除一个订单protected void deleteOrder(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String orderId = WebUtils.parseString(req.getParameter("orderId"));orderService.deleteOrder(orderId);resp.sendRedirect(req.getContextPath()+"/orderServlet?action=showAllOrders");}//订单已到货,修改订单状态protected void arrive(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String orderId = WebUtils.parseString(req.getParameter("orderId"));orderService.arrive(orderId);req.getRequestDispatcher("/pages/order/trans.jsp").forward(req,resp);}/*** 签收* @param req* @param resp* @throws ServletException* @throws IOException*/protected void receiveOrder(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String orderId = WebUtils.parseString(req.getParameter("orderId"));orderService.receiveOrder(orderId);resp.sendRedirect(req.getContextPath()+"/orderServlet?action=showMyOrders");}//查看我的订单protected void showMyOrders(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {User loginUser = (User) req.getSession().getAttribute("user");if (loginUser == null){req.getRequestDispatcher("/pages/user/login.jsp").forward(req,resp);return;}int userId = loginUser.getId();List<Order> orders = orderService.showMyOrders(userId);req.getSession().setAttribute("orders",orders);resp.sendRedirect(req.getContextPath()+"/pages/order/order.jsp");}/*** 发货* @param req* @param resp* @throws ServletException* @throws IOException*/protected void sendOrder(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String orderId = WebUtils.parseString(req.getParameter("orderId"));orderService.sendOrder(orderId);resp.sendRedirect(req.getContextPath()+"/orderServlet?action=showAllOrders");}/*** 查看订单详情* @param req* @param resp* @throws ServletException* @throws IOException*/protected void showOrderDetail(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String orderId = WebUtils.parseString(req.getParameter("orderId"));List<OrderItem> orderItems = orderService.showOrderDetail(orderId);req.setAttribute("orderItems",orderItems);req.getRequestDispatcher("/pages/order/orderDetails.jsp").forward(req,resp);}/*** 查看所有订单* @param req* @param resp* @throws ServletException* @throws IOException*/protected void showAllOrders(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {List<Order> orders = orderService.showAllOrders();req.getSession().setAttribute("orders",orders);req.getRequestDispatcher("/pages/manager/order_manager.jsp").forward(req,resp);}/*** 生成订单* @param req* @param resp* @throws ServletException* @throws IOException*/protected void createOrder(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//先获取cart购物车对象Cart cart = (Cart) req.getSession().getAttribute("cart");//获取userIdUser loginUser = (User) req.getSession().getAttribute("user");if (loginUser == null){req.getRequestDispatcher("/pages/user/login.jsp").forward(req,resp);return;}int userId = loginUser.getId();//调用orderService.createOrder(Cart,UserId)方法,生成订单String orderId = orderService.createOrder(cart, userId);//        req.setAttribute("orderId",orderId);重定向后不能共享,改用session//请求转发到pages/cart/checkout.jsp页面
//        req.getRequestDispatcher("/pages/cart/checkout.jsp").forward(req,resp); 表单重复提交req.getSession().setAttribute("orderId",orderId);resp.sendRedirect(req.getContextPath()+"/pages/cart/checkout.jsp");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {super.doPost(req, resp);}
}

完整项目代码以及jar包请参考:https://github.com/sxlin2021
才疏学浅,多谢指教。

尚硅谷网上书城项目概要相关推荐

  1. 尚硅谷·网上书城项目(一)

    网上书城·尚硅谷 一.项目概述 尚硅谷讲师佟刚的Servlet\Jsp实战项目. 二.功能分析 项目拥有上图所示功能: 1.界面的显示(JSP+EL+JSTL) 2.价格区间查询以及分页(原生态Aja ...

  2. 尚硅谷 网上书城 代码 Book

    首页 注册页面 登录页面 登录 登入成功 我的订单页面 主页面 购物车页面 可以跑通项目源码 链接:https://pan.baidu.com/s/1NpjK1NI0xAQo_Xqep0g5xw 提取 ...

  3. 网上书城java负责_网上书城项目总结(servlet_jsp+javaBean)

    网上书城项目总结 1 项目大纲设计: 需求分析 系统设计 详细设计 权限设计 2 技术选型: Servlet+jsp+javaBean Listener+Filter+jstl+fileupload+ ...

  4. java web网上书城_javaweb网上书城项目

    [实例简介] javaweb网上书城项目,采用ssh框架,mysql数据库. [实例截图] [核心代码] bookstore └── ssh_book ├── WebContent │   ├── M ...

  5. 网上书城项目的需求分析、数据库表设计及前端界面的编写(项目进度一)

    转载请标明出处:https://blog.csdn.net/men_ma/article/details/106847165. 本文出自 不怕报错 就怕不报错的小猿猿 的博客 网上书城项目的需求分析. ...

  6. 尚硅谷大数据项目之电商数仓(4即席查询数据仓库)

    尚硅谷大数据项目之电商数仓(即席查询) (作者:尚硅谷大数据研发部) 版本:V4.0 第1章 Presto 1.1 Presto简介 1.1.1 Presto概念 1.1.2 Presto架构 1.1 ...

  7. JavaWeb网上书城项目总结(初步1.0)

    JavaWeb网上书城项目总结 目录 项目背景与目标 成员组成 模块划分 数据库设计 功能分析+源码 经验总结 (逐步放上博客,先总结) 成员组成 组长:林俊豪(本人) 组员:温尧皓.麦乙迪.邓梓鹏. ...

  8. 网上书城项目的书籍分类列表展示及新书上架和热销书籍效果展示功能(项目进度四)

    网上书城项目的书籍分类列表展示及新书上架和热销书籍效果展示功能(项目进度四) 前言 需实现的目标(效果图) 书籍分类展示 新书上架展示 热销书籍展示 1.书籍分类展示(实现动态加载数据) 1.1 加载 ...

  9. 电商数仓描述_笔记-尚硅谷大数据项目数据仓库-电商数仓V1.2新版

    架构 项目框架 数仓架构 存储压缩 Snappy与LZO LZO安装: 读取LZO文件时,需要先创建索引,才可以进行切片. 框架版本选型Apache:运维麻烦,需要自己调研兼容性. CDH:国内使用最 ...

最新文章

  1. Session 常见操作
  2. Windows环境 安装dlib cv2(python) 总结
  3. WPF Effect 造成的字体模糊
  4. XGBoost、LightGBM的详细对比介绍
  5. 包图网签约神策数据,助力产品优化
  6. 现有工程项目上加响应式
  7. 我这几年呆的这几个公司
  8. cut命令详解(转)
  9. 矩形分割(洛谷P1324题题解,Java语言描述)
  10. 风变python小课离线版_Python是个什么鬼?为什么医学生朋友圈里都是它!
  11. 300页!2020年全网最新Java面试题(附答案)开放下载!超全!!
  12. 高考学文的能报计算机吗,高考志愿填报时,文科生能申报计算机类相关专业吗?...
  13. Go,11 岁生日快乐!
  14. 区块链架构与应用(区块链入门篇)
  15. electron 读取文件夹内容_electron + jQuery +node.js 快速上手之实现写入文件、拖拽打开文件并读取内容的功能...
  16. 使用高德地图获取拍照图片地理位置
  17. Python读取显示raw图片+numpy基本用法记录
  18. 查看表空间及增加表空间
  19. Linux网络容灾,一个简单的两个Linux之间的容灾备份的Demo
  20. 使用代码操作WLAN

热门文章

  1. 1. Rectangle的基本使用
  2. B2C购物商城---MMALL商城概览
  3. 抽象方法示例_示例介绍JavaScript窗口方法
  4. 数美观察|全国网信系统同电信部门处罚违法网站6907家
  5. 三万字-计算机三级-信息安全技术-信息安全保障概述
  6. 加法器(减法器)运算放大电路
  7. APS炒币机器人的投资随记No.4:持续震荡多空焦灼之下后市如何布局
  8. 【信号处理】数字调音台含Matlab源码
  9. Tiktok shop如何将天猫淘宝速卖通等平台产品一键采集自动刊登上货铺货到店铺上
  10. 计算机电源用什么端子,三菱PLC电源端子的接线方法图解