【web 编程技术】基于 B/S 架构的电商平台(java web)

基于 B/S 架构的电商平台(java web)

  • 课程设计实验目的
  • 课程设计实验环境
  • 课程设计功能概述
  • 课程设计需求分析
    • 三层架构图
    • 功能列表
    • 系统用例图
    • 系统活动图-用户端
    • 需求分析
  • 课程设计详细设计
    • 实现过程
      • 数据库
      • BaseServlet 的实现
      • 商品显示模块-分页显示所有商品、查看单个商品详细信息
      • 用户模块-新用户注册、用户登录、用户退出
      • 支付模块-完成在线支付功能
      • 购物车模块-加入商品到购物车、修改所购商品数量
      • 订单模块-提交订单并显示订单信息、用户确认后生成正式订单、用户查看历史订单
      • 收货地址-管理收货地址(增删改查)
      • 管理模块-增加、删除、修改、查找会员、订单、商品信息
    • 测试过程
      • 用户模块-新用户注册、用户登录、用户退出
      • 商品显示模块-分页显示所有商品、查看单个商品详细信息
      • 购物车模块-加入商品到购物车、修改所购商品数量
      • 订单模块-提交订单并显示订单信息、用户确认后生成正式订单、用户查看历史订单
      • 支付模块-完成在线支付功能
      • 收货地址-管理收货地址 (增删改查)
      • 管理模块-增加、删除、修改、查找会员、订单、商品信息
  • 项目代码来源与下载

课程设计实验目的

本次实验旨在通过开发一个基于B/S架构的电商平台,深入学习Web开发技术,掌握相关知识和技能。通过本综合实验可以学到如下内容:

  • Web开发技术:掌握了B/S架构、前端技术(JSP、CSS、JavaScript)和后端技术(Java、Servlet),利用Ajax实现了前后端数据交互,提升了用户体验。
  • 数据库技术:学习了MySQL数据库的使用与管理,设计了安全稳定的数据库结构,并应用了C3P0连接池技术以提高开发效率。
  • 系统开发流程:深入了解了系统开发的全过程,包括需求分析、技术选型、架构设计、编码实现、测试调试等各个环节。
  • 安全防护:掌握了MD5和Base64等加密技术,保护用户隐私和信息安全,并学习了防止SQL注入、XSS攻击等安全措施。
  • 系统功能设计:熟悉了电商平台的业务流程和功能需求,涵盖了商品展示、用户管理、订单处理、支付等功能的设计和实现。
  • 代码设计和优化:运用反射技术创建BaseServlet,实现一个servlet对应多个方法,提高了代码的复用性和可维护性。同时,使用BeanUtils工具类实现了不同对象之间的映射。

课程设计实验环境

  • PyCharm - 用于编写和管理Java代码。
  • MySQL - 用作关系型数据库管理系统,存储和管理数据。
  • Chrome浏览器 -用于调试和展示Web应用。
  • Apache Tomcat 8.5.97 - 用作Web服务器,运行和管理Java Web应用程序

课程设计功能概述

MyShop商城是一个完整的电商购物平台,可通过正确的用户名及其密码进入系统购物。系统分为七大模块,商品展示模块、用户模块、购物车模块、订单模块、支付模块、后台模块。该系统分为用户端和管理端两部分。

  • 用户端:主要功能包括浏览商品,加入购物车,支付订单,查询订单。
  • 管理端:主要功能包括增加、删除、修改、查找会员、订单、商品信息。

该系统有三个参与者,分别为会员、游客和管理员。会员登录后可以浏览商品信息,将商品加入购物车,下单,支付订单;游客可以浏览商品信息,但在加入购物车时会弹出会员登录注册窗口;管理员登录后可以管理商品信息、会员信息以及订单信息。

课程设计需求分析

三层架构图

该系统采用了经典的三层架构模式,分为客户端、Web层、Service层和Dao层。
在这里插入图片描述
通过三层架构图可以看出,在这个系统中,数据流动遵循着清晰的路径:从客户端发起请求,经过Web层接收并解析请求,通过BeanUtils工具类映射参数后调用Service层处理业务逻辑。Service层需要数据库操作,于是调用Dao层与数据库进行交互执行相应的SQL操作。数据结果再经由Dao层返回给Service层,Service层处理结果并返回给Web层。最终,Web层将响应结果反馈给客户端,完成了整个数据流动和处理的过程。

注:由于功能较多,所以将所有功能的三层架构逻辑统一成一个三层架构图

功能列表

在这里插入图片描述

系统用例图

在这里插入图片描述

系统活动图-用户端

在这里插入图片描述

需求分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

课程设计详细设计

实现过程

数据库

drop table if exists address;
drop table if exists cart;
drop table if exists item;
drop table if exists orders;
drop table if exists product;
drop table if exists type;
drop table if exists user;

-- 地址表:存储用户的收货地址信息
create table address(
		a_id     int not null auto_increment comment '地址实体的唯一主键列',
		u_id     int comment '用户实体的主键属性',
		a_name   varchar(30) comment '地址的收件人',
		a_phone  varchar(14) comment '收件人电话',
		a_detail varchar(200) comment '收货人详细地址',
		a_state  int comment '是否是默认地址 0 不是 1是默认地址',
		primary key (a_id)
);

-- 购物车表:存储用户购物车中的商品信息
create table cart(
		c_id    int not null auto_increment comment '购物车的唯一标识',
		u_id    int comment '用户实体的主键属性',
		p_id    int comment '商品的唯一主键',
		c_count decimal(12, 2) comment '购物车小计',
		c_num   int comment '购物车商品数量',
		primary key (c_id)
);

-- 订单项表:记录订单中的商品详情
create table item(
		i_id    int not null auto_increment comment '订单项的唯一标识',
		o_id    varchar(64) comment '订单编号是字符串类型但是也是唯一标识',
		p_id    int comment '商品的唯一主键',
		i_count decimal(12, 2) comment '订单项的小计',
		i_num   int comment '订单项的数量',
		primary key (i_id)
);

-- 订单表:存储用户的订单信息
create table orders(
		o_id    varchar(64) not null comment '订单编号是字符串类型但是也是唯一标识',
		u_id    int comment '用户实体的主键属性',
		a_id    int comment '地址实体的唯一主键列',
		o_count decimal(12, 2) comment '订单的总金额',
		o_time  datetime comment '订单的详细时间',
		o_state int comment '订单状态 0 未付款,1已经付款未发货 2发货待收货 3 收货待评价 4订单完成 5 退货状态',
		primary key (o_id)
);

-- 商品表:存储商品的详细信息
create table product(
		p_id    int not null auto_increment comment '商品的唯一主键',
		t_id    int comment '类别的主键id',
		p_name  varchar(50) comment '商品的名称',
		p_time  date comment '商品的上市时间',
		p_image varchar(100) comment '商品图片的路径',
		p_price decimal(12, 2) comment '商品的价格',
		p_state int comment '商品的热门指数',
		p_info  varchar(200) comment '商品的描述',
		primary key (p_id)
);

-- 类别表:存储商品的类别信息
create table type(
		t_id   int not null auto_increment comment '类别的主键id',
		t_name varchar(20) comment '类别的名称',
		t_info varchar(200) comment '类别的描述',
		primary key (t_id)
);

-- 用户表:存储用户信息,包括会员和管理员信息
create table user(
		u_id       int         not null auto_increment comment '用户实体的主键属性',
		u_name     varchar(20) not null comment '用户账号',
		u_password varchar(64) not null comment '用户密码',
		u_email    varchar(50) not null comment '用户的邮箱!用于激活使用!',
		u_sex      varchar(4) comment '用户性别!',
		u_status   int comment '用户的激活状态 0 未激活 1 激活',
		u_code     varchar(64) comment '邮件激活码',
		u_role     int comment '用户 0 管理员 1',
		primary key (u_id)
);

插入数据

INSERT INTO product(t_id, p_name, p_time, p_image, p_price, p_state, p_info)
VALUES (1, "红米4", "1990-01-01", "image/gwc_xiaomi6.jpg", 1999, 4, "红米4手机,主打性价比!吸引年轻")
     , (1, "红米4", "1990-01-01", "image/liebiao_hongmin4.jpg", 1999, 4, "红米4手机,主打性价比!吸引年轻")
     , (1, "红米4", "1990-01-01", "image/liebiao_hongmin4x.jpg", 1999, 4, "红米4手机,主打性价比!吸引年轻")
     , (1, "红米4", "1990-01-01", "image/liebiao_hongmin42.jpg", 1999, 4, "红米4手机,主打性价比!吸引年轻")
     , (1, "红米4", "1990-01-01", "image/liebiao_xiaomi5.jpg", 1999, 4, "红米4手机,主打性价比!吸引年轻")
     , (1, "红米4", "1990-01-01", "image/liebiao_xiaomi5c.jpg", 1999, 4, "红米4手机,主打性价比!吸引年轻")
     , (1, "红米4", "1990-01-01", "image/liebiao_xiaomi5s.jpg", 1999, 4, "红米4手机,主打性价比!吸引年轻")
     , (1, "红米4", "1990-01-01", "image/liebiao_xiaomi6.jpg", 1999, 4, "红米4手机,主打性价比!吸引年轻")
     , (1, "红米4", "1990-01-01", "image/liebiao_xiaomimix.jpg", 1999, 4, "红米4手机,主打性价比!吸引年轻")
     , (1, "红米4", "1990-01-01", "image/liebiao_xiaomint2.jpg", 1999, 4, "红米4手机,主打性价比!吸引年轻")
     , (1, "红米4", "1990-01-01", "image/liebiao_hongmin4.jpg", 1999, 4, "红米4手机,主打性价比!吸引年轻")
     , (1, "红米4", "1990-01-01", "image/liebiao_hongmin4.jpg", 1999, 4, "红米4手机,主打性价比!吸引年轻")
     , (2, "红米4手机壳", "1990-01-01", "image/peijian2.jpg", 20, 5, "红米4手机壳,用心保护你的手机")
     , (2, "红米4手机壳", "1990-01-01", "image/peijian2.jpg", 20, 5, "红米4手机壳,用心保护你的手机")
     , (2, "红米4手机壳", "1990-01-01", "image/peijian2.jpg", 20, 5, "红米4手机壳,用心保护你的手机")
     , (2, "红米4手机壳", "1990-01-01", "image/peijian2.jpg", 20, 5, "红米4手机壳,用心保护你的手机")
     , (2, "红米4手机壳", "1990-01-01", "image/peijian2.jpg", 20, 9, "红米4手机壳,用心保护你的手机")
     , (2, "红米4手机壳", "1990-01-01", "image/peijian2.jpg", 20, 8, "红米4手机壳,用心保护你的手机")
     , (2, "红米4手机壳", "1990-01-01", "image/peijian2.jpg", 20, 6, "红米4手机壳,用心保护你的手机")
     , (2, "红米4手机壳", "1990-01-01", "image/peijian2.jpg", 20, 7, "红米4手机壳,用心保护你的手机")
     , (2, "红米4手机壳", "1990-01-01", "image/peijian2.jpg", 20, 5, "红米4手机壳,用心保护你的手机")
     , (2, "红米4手机壳", "1990-01-01", "image/peijian2.jpg", 20, 4, "红米4手机壳,用心保护你的手机")
     , (2, "红米4手机壳", "1990-01-01", "image/peijian2.jpg", 20, 3, "红米4手机壳,用心保护你的手机")
     , (2, "红米4手机壳", "1990-01-01", "image/peijian2.jpg", 20, 2, "红米4手机壳,用心保护你的手机")
     , (2, "红米4手机壳", "1990-01-01", "image/peijian2.jpg", 20, 4, "红米4手机壳,用心保护你的手机")
     , (2, "红米4手机壳", "1990-01-01", "image/peijian2.jpg", 20, 1, "红米4手机壳,用心保护你的手机")


INSERT INTO type (t_name, t_info)
VALUES
    ('笔记本', '这是笔记本类别的描述'),
    ('平板', '这是平板类别的描述'),
    ('家电', '这是家电类别的描述'),
    ('路由器', '这是路由器类别的描述'),
    ('服务中心', '这是服务中心类别的描述'),
    ('社区', '这是社区类别的描述');

BaseServlet 的实现

创建一个BaseServlet类,让他去继承HttpServlet!在BaseServlet中写service方法!

BaseServlet是一个类,继承自HttpServlet,其中包含了一个service方法。在service方法中,它实现了以下逻辑:首先,它获取请求中的标识符,然后利用反射机制调用相应的业务逻辑。这样设计的好处在于每个模块的Controller只需要继承BaseServlet,无需重复编写service方法,便于代码的组织和管理。另外,BaseServlet还对返回值进行了优化处理,统一了方法的返回值为字符串,并约定了特殊的标识符格式,如“forward:路径”,以便统一处理转发、重定向或返回字符串的情况。在标识符异常情况下,BaseServlet会默认使用index方法进行处理,确保每个Controller都有默认的入口方法。

package com.itqf.controller;

import com.itqf.utils.Constants;

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.lang.reflect.Method;

/**
 * BaseServlet用于集中处理方法的调用!
 * 以及返回值处理!
 * 以及默认页对应方法!
 */
public class BaseServlet extends HttpServlet {

    /**
     * service方法用于处理所有的HTTP请求
     *
     * @param req HTTP请求对象
     * @param res HTTP响应对象
     * @throws ServletException Servlet异常
     * @throws IOException      IO异常
     */
    @Override
    public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        //1.获取请求参数(标识符)
        String methodStr = req.getParameter(Constants.TAG);


        //2.参数异常:如果method没有获取到值!则跳转到首页(标识符异常处理)
        if (methodStr == null && methodStr.equals("")) {
            methodStr = Constants.INDEX;
        }

        //3.反射调用对应的业务逻辑方法
        //.获取类的class对象
        Class clazz = this.getClass();
        //2.获取方法 参数1:方法名 参数2:方法类型
        try {
            Method method = clazz.getMethod(methodStr, HttpServletRequest.class, HttpServletResponse.class);
            //执行方法 参数1:要执行方法的对象 参数2:执行方法传入句的参数 返回值:执行方法的返回值!如果方法为void,返回值为null
            Object result = method.invoke(this, req, res);
            //集中处理返回值响应
            if (result != null) {
                //转发 重定向  返回字符
                String str = (String) result;
                if (str.startsWith(Constants.FORWARD)) {
                    //转发
                    String path = str.substring(str.indexOf(Constants.FLAG) + 1);
                    req.getRequestDispatcher(path).forward(req, res);
                } else if (str.startsWith(Constants.REDIRECT)) {
                    //重定向
                    String path = str.substring(str.indexOf(Constants.FLAG) + 1);
                    res.sendRedirect(path);
                } else {
                    res.getWriter().println(str);
                }
            }
        } catch (Exception e) {
            //controller 和 service dao 有异常都会到此处!
            e.printStackTrace();
            req.getSession().setAttribute("msg", "程序异常!请稍后再试!");
            res.sendRedirect("/message.jsp");

        }

    }

    /**
     * 当method标识符‘没有值’ 默认赋 index 访问每个controller的index方法!
     * 将方法提取到baseservlet中减少代码冗余!
     * 默认处理:跳转到程序的首页!
     *
     * @param req  HTTP请求对象
     * @param resp HTTP响应对象
     * @return 返回转发到程序首页的路径
     * @throws IOException      IO异常
     * @throws ServletException Servlet异常
     */
    public String index(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        return Constants.FORWARD + "/index.jsp";
    }
}

商品显示模块-分页显示所有商品、查看单个商品详细信息

由于代码量较多,只展示三层架构中 DAO层、WEB层、Service层的代码

  1. Dao
package com.itqf.dao.impl;
	
	import com.itqf.dao.ProductDao;
	import com.itqf.entity.Product;
	import com.itqf.utils.C3P0Utils;
	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.SQLException;
	import java.util.List;
	
	public class ProductDaoImpl implements ProductDao {
		
		/**
		* 根据商品类别ID查询该类别商品总数
		* @param tid 商品类别ID
		* @return 商品总数
		* @throws SQLException SQL异常
		*/
		@Override
		public long selectCountByTid(String tid) throws SQLException {
			QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
			// COUNT()是一个SQL聚合函数,用于计算指定列的行数(记录数)
			String sql = "select count(1) from product where t_id = ?";
			Object result = queryRunner.query(sql, new ScalarHandler(), tid);
			Long total = (Long) result;
			return total;
		}
		
		/**
		* 分页查询指定类别的商品列表
		* @param page 当前页码
		* @param pageSize 每页显示数量
		* @param tid 商品类别ID
		* @return 商品列表
		* @throws SQLException SQL异常
		*/
		@Override
		public List<Product> selectProductByPage(int page, int pageSize, String tid) throws SQLException {
			QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
			String sql = "select p_id as pid, t_id as tid, p_name as pname, p_time as ptime," +
			"p_image as pimage, p_state as pstate, p_info as pinfo, p_price as pprice " +
			"from product where t_id = ? limit ?, ?";
			List<Product> list = queryRunner.query(sql, new BeanListHandler<>(Product.class),
			tid, (page - 1) * pageSize, pageSize);
			return list;
		}
		
		/**
		* 根据商品ID查询商品详细信息
		* @param pid 商品ID
		* @return 商品详细信息
		* @throws SQLException SQL异常
		*/
		@Override
		public Product selectProductByPid(String pid) throws SQLException {
			QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
			String sql = "select p_id as pid, t_id as tid, p_name as pname, p_time as ptime," +
			"p_image as pimage, p_state as pstate, p_info as pinfo, p_price as pprice " +
			"from product where p_id = ?";
			Product product = queryRunner.query(sql, new BeanHandler<>(Product.class), pid);
			return product;
		}
	}
	
  1. Service层
package com.itqf.service.impl;
	
	import com.itqf.dao.ProductDao;
	import com.itqf.dao.impl.ProductDaoImpl;
	import com.itqf.entity.PageBean;
	import com.itqf.entity.Product;
	import com.itqf.service.ProductService;
	
	import java.sql.SQLException;
	import java.util.List;
	
	public class ProductServiceImpl implements ProductService {
		
		/**
		* 根据类别ID和页码查询对应商品信息并封装成分页对象
		* @param tid 商品类别ID
		* @param page 当前页码
		* @param pageSize 每页显示数量
		* @return 分页对象
		* @throws SQLException SQL异常
		*/
		@Override
		public PageBean<Product> findPage(String tid, int page, int pageSize) throws SQLException {
			ProductDao productDao = new ProductDaoImpl();
			long count = productDao.selectCountByTid(tid); // 查询总条数
			List<Product> list = productDao.selectProductByPage(page, pageSize, tid); // 查询当前页对应的商品
			return new PageBean<>(list, page, pageSize, count);
		}
		
		/**
		* 根据商品ID查询商品详细信息
		* @param pid 商品ID
		* @return 商品详细信息
		* @throws SQLException SQL异常
		*/
		@Override
		public Product findProductByPid(String pid) throws SQLException {
			ProductDao productDao = new ProductDaoImpl();
			Product product = productDao.selectProductByPid(pid);
			return product;
		}
	}
  1. Web层(对应controller包的内容)
package com.itqf.controller;
	
	import com.itqf.entity.PageBean;
	import com.itqf.entity.Product;
	import com.itqf.service.ProductService;
	import com.itqf.service.impl.ProductServiceImpl;
	import com.itqf.utils.Constants;
	
	import javax.servlet.annotation.WebServlet;
	import javax.servlet.http.HttpServletRequest;
	import javax.servlet.http.HttpServletResponse;
	import java.sql.SQLException;
	
	/**
	* 分页商品展示的controller
	*/
	@WebServlet("/product")
	public class ProductController extends BaseServlet {
		
		/**
		* 展示商品列表
		* @param request HTTP请求对象
		* @param response HTTP响应对象
		* @return 页面转发路径
		* @throws SQLException SQL异常
		*/
		public String show(HttpServletRequest request, HttpServletResponse response) throws SQLException {
			// 1.接收请求参数tid 类别id
			String tid = request.getParameter("tid");
			// 页容量
			int pageSize = 8;
			// 从前端获取当前页数
			String currentPage = request.getParameter("currentPage");
			int page = 1; // 默认第一页
			if (currentPage != null) {
				page = Integer.parseInt(currentPage);
			}
			
			// 2.调用业务逻辑得到前端需要展示的PageBean
			ProductService productService = new ProductServiceImpl();
			PageBean<Product> pageBean = productService.findPage(tid, page, pageSize);
			// 3.响应
			request.setAttribute("pageBean", pageBean);
			
			return Constants.FORWARD + "/goodsList.jsp";
		}
		
		/**
		* 展示商品详情
		* @param request HTTP请求对象
		* @param response HTTP响应对象
		* @return 页面转发路径
		* @throws SQLException SQL异常
		*/
		public String detail(HttpServletRequest request, HttpServletResponse response) throws SQLException {
			// 1.获取请求参数
			String pid = request.getParameter("pid");
			
			// 2.调用业务逻辑
			ProductService productService = new ProductServiceImpl();
			Product product = productService.findProductByPid(pid);
			// 3.响应
			request.setAttribute("product", product);
			return Constants.FORWARD + "/goodsDetail.jsp";
		}
	}
	
	\end{lstlisting}
	
  1. 前端页面(对应goodsList.jsp 和goodsDetail.jsp的内容)

用户模块-新用户注册、用户登录、用户退出

  1. DAO层(对应UserDaoImpl.java包的内容)
	package com.itqf.dao.impl;
	
	import com.itqf.dao.UserDao;
	import com.itqf.entity.User;
	import com.itqf.utils.C3P0Utils;
	import com.itqf.utils.Constants;
	import org.apache.commons.dbutils.QueryRunner;
	import org.apache.commons.dbutils.handlers.BeanHandler;
	
	import java.sql.SQLException;
	
	/**
	* 数据库访问实现类
	*/
	public class UserDaoImpl implements UserDao {
		@Override
		public User selectUserByUname(String username) throws SQLException {
			//1.创建一个QueryRunner对象 获取一个数据库连接池数据源。C3P0是一个流行的开源数据库连接池
			QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
			//2.执行SQL语句
			String sql = "select u_id as uid , u_name as username , u_password as upassword" +
			", u_sex as usex , u_status as ustatus , u_code as code , u_email as email " +
			", u_role as urole from user where u_name = ?";
			User user = queryRunner.query(sql, new BeanHandler<User>(User.class), username); //将查询结果映射到一个Java对象中
			
			return user;
		}
		
		@Override
		public int insertUser(User user) throws SQLException {
			//1.创建一个QueryRunner对象 获取一个数据库连接池数据源。C3P0是一个流行的开源数据库连接池
			QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
			//2.执行SQL语句 插入数据
			String sql = "insert into user (u_name,u_password,u_sex,u_status," +
			"u_code,u_email,u_role) value (?,?,?,?,?,?,?)";
			
			int rows = queryRunner.update(sql, user.getUsername(), user.getUpassword(), user.getUsex(),
			user.getUstatus(), user.getCode(), user.getEmail(), user.getUrole());
			return rows;
			
		}
		
		@Override
		public User selectUserByCode(String code) throws SQLException {
			//1.创建一个QueryRunner对象 获取一个数据库连接池数据源。C3P0是一个流行的开源数据库连接池
			QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
			//2.执行SQL语句
			String sql = "select u_id as uid , u_name as username , u_password as upassword" +
			", u_sex as usex , u_status as ustatus , u_code as code , u_email as email " +
			", u_role as urole from user where u_code = ?";
			User user = queryRunner.query(sql, new BeanHandler<User>(User.class), code); //将查询结果映射到一个Java对象中
			
			return user;
		}
		
		@Override
		public int updataStatusByid(int uid) throws SQLException {
			//1.创建一个QueryRunner对象 获取一个数据库连接池数据源。C3P0是一个流行的开源数据库连接池
			QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
			String sql = "update user set u_status = ? where u_id = ?";
			
			int row = queryRunner.update(sql, Constants.USER_ACTIVE, uid);
			return row;
		}
	}
  1. Service层(对应UserDaoImpl.java包的内容)
package com.itqf.service.impl;

import com.itqf.dao.UserDao;
import com.itqf.dao.impl.UserDaoImpl;
import com.itqf.entity.User;
import com.itqf.service.UserService;
import com.itqf.utils.Constants;
import com.itqf.utils.EmailUtils;
import com.itqf.utils.MD5Utils;

import java.sql.SQLException;

public class UserServiceImpl implements UserService {
	
	/**
	* 验证注册用户名是否可用
	*
	* @param username 被检测的用户名
	* @return
	* @throws SQLException
	*/
	@Override
	public boolean checkedUser(String username) throws SQLException {
		//1.创建dao访问对象
		UserDao userDao = new UserDaoImpl();
		//2.执行结果
		User user = userDao.selectUserByUname(username);
		//3.处理返回值
		if (user != null) {
			return true;
		}
		return false;
	}
	
	/**
	* 用户注册逻辑
	*
	* @param user
	* @return
	* @throws SQLException
	*/
	@Override
	public int registerUser(User user) throws SQLException {
		
		//1.用户保存到数据库
		UserDao userDao = new UserDaoImpl();
		
		int row = userDao.insertUser(user);
		
		//2.发送一封邮件
		EmailUtils.sendEmail(user);
		return row;
	}
	
	/**
	* 激活
	*
	* @param code 根据激活码进行激活
	* @return
	* @throws SQLException
	*/
	@Override
	public int activeUser(String code) throws SQLException {
		UserDao userDao = new UserDaoImpl();
		//1.根据激活码查找用户
		User user = userDao.selectUserByCode(code);
		if (user == null) {
			return Constants.ACTIVE_FAIL;//0激活失败
		}
		//2.判断用户是否激活
		if (user.getUstatus().equals(Constants.USER_ACTIVE)) {
			return Constants.ACTIVE_ALREADY;
		}
		//3.进行激活操作
		int i = userDao.updataStatusByid(user.getUid());
		if (i > 0) {
			return Constants.ACTIVE_SUCCESS;
		}
		return Constants.ACTIVE_FAIL;
	}
	
	/**
	* 登录业务
	*
	* @param username
	* @param password
	* @return
	*/
	@Override
	public User login(String username, String password) throws SQLException {
		//1.需要密码用md5处理
		String md5password = MD5Utils.md5(password);
		
		//2.根据用户名查找用户
		UserDao userDao = new UserDaoImpl();
		User user = userDao.selectUserByUname(username);
		
		if (user != null && user.getUpassword().equals(md5password)) {
			return user;
		}
		
		return null;
	}
}

	
  1. Web层(对应UserController.java包的内容)


package com.itqf.controller;

import com.itqf.entity.User;
import com.itqf.service.UserService;
import com.itqf.service.impl.UserServiceImpl;
import com.itqf.utils.Base64Utils;
import com.itqf.utils.Constants;
import com.itqf.utils.MD5Utils;
import com.itqf.utils.RandomUtils;
import org.apache.commons.beanutils.BeanUtils;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.Map;

/**
* 用户用户模块的controller
*/
@WebServlet("/user")
public class UserController extends BaseServlet {
	
	/*用于检查用户是否存在的方法,根据请求中的用户名,调用 UserService 中的方法检查用户是否存在。*/
	public String check(HttpServletRequest request, HttpServletResponse response) throws SQLException {
		//1.获取用户名
		String username = request.getParameter("username");
		if (username == null) {
			return Constants.HAS_USER; //不能注册
		}
		// 2.调用业务逻辑判断用户名是否存在
		UserService userService = new UserServiceImpl();
		boolean b = userService.checkedUser(username);
		// 3.响应字符串  存在:1 不存在:0
		if (b) {
			//用户存在
			return Constants.HAS_USER;
		}
		return Constants.NOT_HAS_USER;
	}
	
	/*用于处理用户注册请求,获取用户信息并调用 UserService 完成用户注册。*/
	public String register(HttpServletRequest request, HttpServletResponse response) throws SQLException {
		//1.获取用户信息
		Map<String, String[]> parameterMap = request.getParameterMap();
		User user = new User();
		try {
			BeanUtils.populate(user, parameterMap); //映射到user
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		
		//2.完善用户信息
		user.setUstatus(Constants.USER_NOT_ACTIVE); //默认未激活状态0,激活1
		user.setUrole(Constants.ROLE_CUSTOMER); //普通客户0 管理员1
		user.setCode(RandomUtils.createActive());//激活码
		// 密码加密,md5进行加密
		user.setUpassword(MD5Utils.md5(user.getUpassword()));
		
		//3.调用用户业务逻辑进行注册
		UserService userService = new UserServiceImpl();
		try {
			userService.registerUser(user);
		} catch (SQLException e) {
			e.printStackTrace();
			request.setAttribute("registerMsg", "注册失败!");
			return Constants.FORWARD + "/register.jsp";
		}
		
		//4.响应 注册成功跳转激活页面
		return Constants.FORWARD + "/registerSuccess.jsp";
	}
	
	public String active(HttpServletRequest request, HttpServletResponse response) throws SQLException {
		//1.获取激活码
		//已经转成base64
		String c = request.getParameter("c");
		System.out.println("c="+c);
		//base64翻转
		String code = Base64Utils.decode(c);
		//2.调用激活的业务逻辑
		UserService userService = new UserServiceImpl();
		int i = userService.activeUser(code);
		
		//3.响应(激活失败(code没有找到) 已经激活 激活成功)
		if (i == Constants.ACTIVE_FAIL) {
			request.setAttribute("msg", "未激活成功!");
		} else if (i == Constants.ACTIVE_SUCCESS) {
			request.setAttribute("msg", "激活成功,请登录!");
		} else {
			request.setAttribute("msg", "已经激活");
		}
		return Constants.FORWARD + "/message.jsp";
	}
	
	/**
	* 1.前端提交账号密码和验证码
	* 2.对比验证码 成功 ---》 对比账号密码
	* 3.对比账号密码
	* 失败: --》 回到登录页面 进行提示
	* 成功: --》 未激活  登录页面 进行提示
	* --》 已激活  程序的首页  将用户放入session共享域
	*/
	
	public String login(HttpServletRequest request, HttpServletResponse response) throws SQLException {
		
		//1.获取请求参数(用户名,密码,验证码)
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		String code = request.getParameter("code");//用户输入的验证码
		String auto = request.getParameter("auto"); //自动登录标识
		//正确的验证码
		HttpSession session = request.getSession();
		String codestr = (String) session.getAttribute("code");
		
		
		//2.判断验证码是否正确
		// 不考虑大小写比较
		//        System.out.println("输入:"+code);
		//        System.out.println("正确"+codestr);
		//        System.out.println(code == null || !code.equalsIgnoreCase(codestr));
		
		if (code == null || !code.equalsIgnoreCase(codestr)) {
			request.setAttribute("msg", "验证码错误");
			return Constants.FORWARD + "/login.jsp";
		}
		//3.调用业务逻辑判断账户密码
		UserService userService = new UserServiceImpl();
		User user = userService.login(username, password);
		
		//4.响应
		//user 等于null证明账号或者密码错误
		//user 不为null 但是user的状态是未激活状态
		if (user == null) {
			request.setAttribute("msg", "账号或者密码错误");
			return Constants.FORWARD + "/login.jsp";
		}
		if (user.getUstatus().equals(Constants.USER_NOT_ACTIVE)) {
			request.setAttribute("msg", "账号未激活!");
			return Constants.FORWARD + "/login.jsp";
		}
		//把用户放在共享域session中
		session.setAttribute("loginUser", user);
		
		//判断是否勾选自动登录
		if (auto == null) {
			//没有勾选
			//将本地浏览器的存储的cookie清空
			Cookie cookie = new Cookie(Constants.AUTO_NAME, "");
			cookie.setPath("/");//将 Cookie 的路径设置为根路径,表示该 Cookie 对于整个网站都是可见的
			cookie.setMaxAge(0);//最大存活时间设置为 0
			response.addCookie(cookie);
		} else {
			String content = username + Constants.FLAG + password;
			content = Base64Utils.encode(content);
			//自动登录数据库存储2周
			Cookie cookie = new Cookie(Constants.AUTO_NAME, content);
			cookie.setPath("/");
			cookie.setMaxAge(14 * 24 * 60 * 60);
			response.addCookie(cookie);
		}
		
		return Constants.REDIRECT + "/index.jsp";
	}
	
	/**
	* 注销登录!清空数据!跳转到登录页面
	*
	* @param request
	* @param response
	* @return
	*/
	public String logOut(HttpServletRequest request, HttpServletResponse response) {
		//1.清空session中用户数据
		HttpSession session = request.getSession();
		session.removeAttribute("loginUser");
		
		//2.清空和覆盖cooki存储的自动登录
		Cookie cookie = new Cookie(Constants.AUTO_NAME, "");
		cookie.setPath("/");
		cookie.setMaxAge(0);
		response.addCookie(cookie);
		
		//3.转发到登录页面
		request.setAttribute("msg", "注销登录成功");
		return  Constants.FORWARD + "/login.jsp";
	}
	
}
	
  1. 前端页面(对应login.jsp的内容)

支付模块-完成在线支付功能

  1. DAO层(对应OrdersDaoImpl.java的内容)
 public void updateStateByOid(String oid) throws SQLException {
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		
		String sql = "update orders set o_state = ? where o_id = ?;";
		
		queryRunner.update(sql, 2, oid);
	}
  1. Service层(对应OrdersServiceImpl.java的内容)
public void updateStateByOid(String oid) throws SQLException {
		OrdersDao ordersDao = new OrdersDaoImpl();
		ordersDao.updateStateByOid(oid);
	}
  1. Web层(对应PayController.java的内容)
package com.itqf.controller;
	
	import com.alipay.api.AlipayApiException;
	import com.alipay.api.AlipayClient;
	import com.alipay.api.DefaultAlipayClient;
	import com.alipay.api.domain.AlipayTradePagePayModel;
	import com.alipay.api.internal.util.AlipaySignature;
	import com.alipay.api.request.AlipayTradePagePayRequest;
	import com.itqf.service.OrdersService;
	import com.itqf.service.impl.OrdersServiceImpl;
	import com.itqf.utils.AlipayConfig1;
	import com.itqf.utils.Constants;
	
	import javax.servlet.annotation.WebServlet;
	import javax.servlet.http.HttpServletRequest;
	import javax.servlet.http.HttpServletResponse;
	import java.io.IOException;
	import java.io.PrintWriter;
	import java.io.UnsupportedEncodingException;
	import java.sql.SQLException;
	import java.util.HashMap;
	import java.util.Iterator;
	import java.util.Map;
	
	
	@WebServlet("/pay")
	public class PayController extends BaseServlet {
		
		
		public void createAiliPayForm(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
			//接收订单信息
			String orderID = request.getParameter("orderId");
			String orderPrice = request.getParameter("price");
			String orderBody = request.getParameter("body");
			
			if (orderID != null) {
				// 商户订单号,商户网站订单系统中唯一订单号,必填
				String out_trade_no = new String(orderID.getBytes("ISO-8859-1"), "UTF-8");
				// 订单名称,必填
				String subject = new String(orderBody.getBytes("ISO-8859-1"), "UTF-8");
				// 付款金额,必填
				String total_amount = new String(orderPrice.getBytes("ISO-8859-1"), "UTF-8");
				// 商品描述,可空
				String body = "";
				// 超时时间 可空
				String timeout_express = "8m";
				// 销售产品码 必填
				String product_code = "FAST_INSTANT_TRADE_PAY";
				/**********************/
				// SDK 公共请求类,包含公共请求参数,以及封装了签名与验签,开发者无需关注签名与验签
				//调用RSA签名方式
				AlipayClient client = new DefaultAlipayClient(AlipayConfig1.URL, AlipayConfig1.APPID, AlipayConfig1.RSA_PRIVATE_KEY, AlipayConfig1.FORMAT, AlipayConfig1.CHARSET, AlipayConfig1.ALIPAY_PUBLIC_KEY, AlipayConfig1.SIGNTYPE);
				AlipayTradePagePayRequest alipay_request = new AlipayTradePagePayRequest();
				
				//  封装请求支付信息
				// AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
				AlipayTradePagePayModel model = new AlipayTradePagePayModel();
				model.setOutTradeNo(out_trade_no);
				model.setSubject(subject);
				model.setTotalAmount(total_amount);
				model.setBody(body);
				model.setTimeoutExpress(timeout_express);
				model.setProductCode(product_code);
				alipay_request.setBizModel(model);
				
				
				// 设置异步通知地址
				alipay_request.setNotifyUrl(AlipayConfig1.notify_url);
				// 设置同步地址
				alipay_request.setReturnUrl(AlipayConfig1.return_url);
				
				// form表单生产
				String form = "";
				try {
					// 调用SDK生成表单
					form = client.pageExecute(alipay_request).getBody();
					response.setContentType("text/html;charset=" + AlipayConfig1.CHARSET);
					response.getWriter().write(form);//直接将完整的表单html输出到页面
					response.getWriter().flush();
					response.getWriter().close();
				} catch (AlipayApiException | IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
		public String AiliPayReturnNotice(HttpServletRequest request, HttpServletResponse response) throws IOException, AlipayApiException, SQLException {
			
			PrintWriter out = response.getWriter();
			// 功能:支付宝服务器同步通知页面
			//获取支付宝GET过来反馈信息
			Map<String, String> params = new HashMap<String, String>();
			Map<String, String[]> requestParams = request.getParameterMap();
			for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
				String name = (String) iter.next();
				String[] values = (String[]) requestParams.get(name);
				String valueStr = "";
				for (int i = 0; i < values.length; i++) {
					valueStr = (i == values.length - 1) ? valueStr + values[i]
					: valueStr + values[i] + ",";
				}
				//乱码解决,这段代码在出现乱码时使用
				valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
				params.put(name, valueStr);
			}
			
			boolean verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig1.ALIPAY_PUBLIC_KEY, AlipayConfig1.CHARSET, AlipayConfig1.SIGNTYPE); //调用SDK验证签名
			String out_trade_no1 = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
			OrdersService ordersService1 = new OrdersServiceImpl();
			ordersService1.updateStateByOid(out_trade_no1);
			
			if (!verify_result) {
				return Constants.FORWARD + "order?method=show";
			} else {
				out.println("支付失败");
				return null;
			}
			
		}
	}
	
  1. 支付宝配置文件(对应com/itqf/utils/AlipayConfig1.java的内容)
package com.itqf.utils;
	
	public class AlipayConfig1 {
		// 商户appid
		public static String APPID = "9021033645090";
		// 私钥 pkcs8格式的
		public static String RSA_PRIVATE_KEY = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCZIvxaCWfWs0ZrfoTFCaGiP3w4Y/54TZBjncd5216fBRdyAc1wqP+XcSthm4E0P/6WfEFtC81EU1GBJje0em4m0CNCz985UuMHonGxPKEjH6oQuZT9sWoyqDlBSwqrq5p7CFosDrHJc13ih284kNGTUbnTC8e4q7sVIO2JGHNY1Bd6tStX5QbZwTjfO6crMM8iTYlrX2dIWzuOgXvYzbRn7x2NGg1004tiH1f8Slqa3RxoICKeniWPkvZVFRVFKPHeC+yPSkeudP7AX38kXhpEYg9UNxnL1Y1ZgiZ9ZIjNCQwXnZk9qLeJtJwwxunxYoAt5GnrjkUb48xuOSlrFBJFAgMBAAECggEAIQh7+QwYWyb25M844qwOMsqRCDUBun+4ytRJKE8a3SCjCxO6djfuUoO2AOsjdtrrFxkcn+Iw2DFE3qAY2hSi2DqDsLDYjSwFDyuKbNoQRFxbOhpeOk9gAidpml0OozN0Ml/9240b6sG5GdlvM3uByc6SUCU1Yu+gfpFIzA77KsjXwEDC6tBlMBp/BdF8mtA6Pj6+oC9QkSIvUIkVLDjd1kgMxKQXkmrYx3zlaysSpSzd4IzulaqYO80AFnBxL6dTOze0L3s+5u3jnHs8Wy/esn6PslkPzPtj5XXhkuENVvk57dJzo8oVslt3s7kVa+eTiQTC3Qy/T2OQxAKPauJNLQKBgQDXoMbtYj4yA0nXrQuptuSruqtJaWI+fDsU/9DjZWRMzU07rgo4kiOrXo0nrADbogzLGqmauonqOiTNB5l3GAC1R9I26OMF2TH6UbWkpLhXgtuNb0CGtVWXAwNQd9yWNshqyvbe40kwE4KkKtr0qKcuaMGDCqCnIGT0zYIoqx3JfwKBgQC1zvKVwd+xLE5vHaSn0E9OZ2qtZw23DLkfiU3tcle2LJbH6MnkhaNN30mX6Ubo65p2QScWGrWLT9SfDemUXB8TapXItwTnJHjhXhQwiugqsTR47qx4yyWaXhGfe62ALUkIwKEfwZ1hBwYpzMsSCmb66S9c10Pqbx7dSQuwTcZeOwKBgQCIQzLSun3BTzCv2cwAAPL6zukFaFJMWGdhutN/kAhVPHvtFeuhmkBuQD8Fbf3QzdQ12XCKtg0Hdpzg8Ed76jAwXuWqC3vDq2CY5l/aXrmbm7cw5rgpKJig6KeEh2pfhtkaG47shUcv2XR6WBar+5RCkLKRI/soAiGqTeBN4Oze8wKBgDMUgsman+uaZCsJ7BIOD8oaejlf49WTKIv4usFEx+nyGybte5PODDS70GRy8S5Ny6b/5Shrtqf+dOF/Oiopu71ry8uJyEHc2G2RTiDZViNwiCqV/DUv9k+psE/bosKJdqST4nEWp83z+EJUPJXEAGzsiRcPkBBUyhooBLWzFFGzAoGATM1Qk27OkQ6TYNEqd0Oypm1BE5L1DLFiU5EBXWxeUM1PCOqXSemFjN3X1PIkaZ5ASLM8yqZk+XKHMXjF1T3iL9q76ohj0LGnahTF48H6m76R9Az8vmEztops9XZi9YVRMlgoDTyedHhsbzboHZA8YSykYqteX+F2KFWYpQ="; // 服务器异步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
		public static String notify_url = "http://localhost/alipay.trade.wap.pay-JAVA-UTF-8/notify_url.jsp";
		// 页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址
		public static String return_url = "http://localhost:8080/pay?method=AiliPayReturnNotice";
		// 请求网关地址
		public static String URL = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
		// 编码
		public static String CHARSET = "UTF-8";
		// 返回格式
		public static String FORMAT = "json";
		// 支付宝公钥
		public static String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmSL8Wgln1rNGa36ExQmhoj98OGP+eE2QY53HedtenwUXcgHNcKj/l3ErYZuBND/+lnxBbQvNRFNRgSY3tHpuJtAjQs/fOVLjB6JxsTyhIx+qELmU/bFqMqg5QUsKq6uaewhaLA6xyXNd4odvOJDRk1G50wvHuKu7FSDtiRhXerUrV+UG2cE43zunKzDPIk2Ja19nSFs7joF72M20Z+8djRoNdNOLYh9X/Epamt0caCAinp4lj5L2VRUVRSjx3gvsj0pHrnT+wF9/JF4aRGIPVDcZy9WNWYImfWSIzQkMF52ZPai3ibScMMbp8WKALeRp645FG+PMbjkpaxQSRQIDAQAB"; // 日志记录目录
		public static String log_path = "/log";
		// RSA2
		public static String SIGNTYPE = "RSA2";
	}
	

购物车模块-加入商品到购物车、修改所购商品数量

  1. DAO层(对应CartDaoImpl.java的内容)
package com.itqf.dao.impl;

import com.itqf.dao.CartDao;
import com.itqf.entity.Cart;
import com.itqf.entity.Product;
import com.itqf.utils.C3P0Utils;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;

import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class CartDaoImpl implements CartDao {
	@Override
	public Cart hasCart(int uid, String pid) throws SQLException, InvocationTargetException, IllegalAccessException {
		//cart --> product 连接查询 多表查询
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		String sql = "select p.p_name as pname,p.p_id as pid,p.t_id as tid,p.p_time as ptime,p.p_image as pimage,p_state as pstate,p.p_info as pinfo, p.p_price as pprice,c.c_id as cid,c.u_id as uid,c.c_count as ccount ,c.c_num as cnum from product p join cart c on p.p_id = c.p_id where c.u_id = ? and c.p_id = ?";
		
		Map<String, Object> query = queryRunner.query(sql, new MapHandler(), uid, pid);
		
		
		if (query == null) {
			return null;
		}
		
		
		Cart cart = new Cart();
		Product product = new Product();
		BeanUtils.populate(cart, query);
		BeanUtils.populate(product, query);
		cart.setProduct(product);
		
		//        System.out.println("Query result: " + query);
		//        System.out.println("cart"+cart);
		//        System.out.println("product"+product);
		
		//方法2
		//        List<Map<String, Object>> list = queryRunner.query(sql, new MapListHandler(),  uid, pid);
		//        if (list == null) {
			//            return null;
			//        }
		//        List<Cart> carts = new ArrayList<>();
		//        Cart cart = new Cart();
		//        Product product = new Product();
		//        BeanUtils.populate(cart, list.get(0));
		//        BeanUtils.populate(product, list.get(0));
		//        cart.setProduct(product);
		//        carts.add(cart);
		
		//方法3
		//        product.setPname((String) query.get("pname"));
		//        product.setPid((Integer) query.get("pid"));
		//        product.setTid((Integer) query.get("tid"));
		//        product.setPtime((Date) query.get("ptime"));
		//        product.setPimage((String) query.get("pimage"));
		//        product.setPstate((Integer) query.get("pstate"));
		//        product.setPinfo((String) query.get("pinfo"));
		//        product.setPprice((BigDecimal) query.get("pprice"));
		//
		//        cart.setCid((Integer) query.get("cid"));
		//        cart.setUid((Integer) query.get("uid"));
		//        cart.setCcount((BigDecimal) query.get("ccount"));
		//        cart.setCnum((Integer) query.get("cnum"));
		//
		//        cart.setProduct(product);
		
		return cart;
	}
	
	@Override
	public void updateCart(Cart cart) throws SQLException {
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		String sql = "update cart set c_num = ? , c_count = ? where c_id = ?";
		int n = queryRunner.update(sql, cart.getCnum(), cart.getCcount(), cart.getCid());
	}
	
	@Override
	public void insertCart(Cart cart) throws SQLException {
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		String sql = "insert into cart (u_id,p_id,c_num,c_count) value(?,?,?,?)";
		int n = queryRunner.update(sql, cart.getUid(), cart.getProduct().getPid(), cart.getCnum(), cart.getCcount());
	}
	
	@Override
	public List<Cart> selectCartsByUid(int uid) throws SQLException, InvocationTargetException, IllegalAccessException {
		
		//注意 查询cart需要关联到商品表
		//cart --> product 连接查询 多表查询
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		
		String sql = "select p.p_name as pname,p.p_id as pid,p.t_id as tid," +
		"p.p_time as ptime,p.p_image as pimage,p_state as pstate," +
		"p.p_info as pinfo, p.p_price as pprice,c.c_id as cid,c.u_id as uid,c.c_count as ccount," +
		"c.c_num as cnum from product p join cart c on p.p_id = c.p_id where" +
		" c.u_id = ?;";
		
		List<Map<String, Object>> list = queryRunner.query(sql, new MapListHandler(), uid);
		
		if (list == null) {
			return null;
		}
		
		List<Cart> carts = new ArrayList<>();
		
		for (Map<String, Object> map : list) {
			//cart + product
			Cart cart = new Cart();
			Product product = new Product();
			
			BeanUtils.populate(cart, map);
			BeanUtils.populate(product, map);
			
			cart.setProduct(product);
			carts.add(cart);
		}
		
		
		return carts;
	}
	
	@Override
	public void deleteCartByCid(String cid) throws SQLException {
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		
		String sql = "delete from cart where c_id = ?;";
		
		int update = queryRunner.update(sql, cid);
		
	}
	
	@Override
	public void updateByCid(BigDecimal count, BigDecimal cnumbig, String cid) throws SQLException {
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		String sql = "update cart set c_count = ? , c_num = ? where c_id = ?;";
		queryRunner.update(sql, count, cnumbig, cid);
	}
	
	@Override
	public void deleteCartByUid(String uid) throws SQLException {
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		String sql = "delete from cart where u_id = ?;";
		queryRunner.update(sql, uid);
	}
	
	
}

  1. Service层(对应CartServiceImpl.java的内容)
package com.itqf.service.impl;

import com.itqf.dao.CartDao;
import com.itqf.dao.ProductDao;
import com.itqf.dao.impl.CartDaoImpl;
import com.itqf.dao.impl.ProductDaoImpl;
import com.itqf.entity.Cart;
import com.itqf.entity.Product;
import com.itqf.service.CartService;

import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.List;

public class CartServiceImpl implements CartService {
	@Override
	public void createCart(int uid, String pid) throws SQLException, InvocationTargetException, IllegalAccessException {
		//1.判断是否已存在
		CartDao cartDao = new CartDaoImpl();
		
		Cart cart = cartDao.hasCart(uid, pid);
		
		
		if (cart != null) {
			//2.存在 则修改购物车
			cart.setCnum(cart.getCnum() + 1);
			cartDao.updateCart(cart);
		} else {
			//3.不存在 则添加
			//根据商品id查询商品
			ProductDao productDao = new ProductDaoImpl();
			Product product = productDao.selectProductByPid(pid);
			
			cart = new Cart();
			cart.setCnum(1);
			cart.setPid(Integer.parseInt(pid));
			cart.setProduct(product);
			cart.setUid(uid);
			
			cartDao.insertCart(cart);
		}
		
		
	}
	
	@Override
	public List<Cart> findAll(int uid) throws SQLException, InvocationTargetException, IllegalAccessException {
		CartDao cartDao = new CartDaoImpl();
		List<Cart> carts = cartDao.selectCartsByUid(uid);
		return carts;
	}
	
	@Override
	public void deleteCart(String cid) throws SQLException {
		CartDao cartDao = new CartDaoImpl();
		cartDao.deleteCartByCid(cid);
	}
	
	@Override
	public void updateCar(String cid, String price, String cnum) throws SQLException {
		BigDecimal cnumbig = new BigDecimal(cnum);
		BigDecimal pricebig = new BigDecimal(price);
		
		
		BigDecimal count = pricebig.multiply(cnumbig);
		
		
		CartDao cartDao = new CartDaoImpl();
		cartDao.updateByCid(count, cnumbig, cid);
	}
	
	@Override
	public void clearCart(String uid) throws SQLException {
		CartDao cartDao = new CartDaoImpl();
		cartDao.deleteCartByUid(uid);
	}
	
	
}

  1. Web层(对应CartController.java包的内容)
package com.itqf.controller;

import com.itqf.entity.Cart;
import com.itqf.entity.User;
import com.itqf.service.CartService;
import com.itqf.service.impl.CartServiceImpl;
import com.itqf.utils.Constants;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.List;

@WebServlet("/cart")
public class CartController extends BaseServlet {
	
	// 创建购物车
	public String create(HttpServletRequest request, HttpServletResponse response) throws IllegalAccessException, SQLException, InvocationTargetException {
		
		// 1.判断是否已经登录
		HttpSession session = request.getSession();
		User user = (User) session.getAttribute("loginUser");
		if (user == null) {
			session.setAttribute("msg", "添加购物车必须先登录!");
			return Constants.REDIRECT + "/login.jsp";
		}
		
		// 2.商品的id和用户id
		int uid = user.getUid();
		String pid = request.getParameter("pid");
		
		CartService cartService = new CartServiceImpl();
		cartService.createCart(uid, pid);
		
		return Constants.FORWARD + "/cartSuccess.jsp";
	}
	
	
	// 展示购物车
	public String show(HttpServletRequest request, HttpServletResponse response) throws IllegalAccessException, SQLException, InvocationTargetException {
		// 1.判断是否已经登录
		HttpSession session = request.getSession();
		User user = (User) session.getAttribute("loginUser");
		if (user == null) {
			session.setAttribute("msg", "添加购物车必须先登录!");
			return Constants.REDIRECT + "/login.jsp";
		}
		
		// 2.获取参数
		int uid = user.getUid();
		
		// 3.调用业务逻辑进行数据查询
		CartService cartService = new CartServiceImpl();
		List<Cart> list = cartService.findAll(uid);
		
		request.setAttribute("list", list);
		
		return Constants.FORWARD + "/cart.jsp";
	}
	
	// 删除购物车中的商品
	public String delete(HttpServletRequest request, HttpServletResponse response) throws SQLException {
		// 1.获取cid
		String cid = request.getParameter("cid");
		
		// 2.调用业务逻辑进行删除
		CartService cartService = new CartServiceImpl();
		cartService.deleteCart(cid);
		
		// 3.转发到展示的处理方法中
		return Constants.FORWARD + "/cart?method=show";
	}
	
	// 更新购物车中商品的数量和价格
	public String update(HttpServletRequest request, HttpServletResponse response) throws SQLException {
		// 1.获取cid
		String cid = request.getParameter("cid");
		String price = request.getParameter("price"); // 商品的单价
		String cnum = request.getParameter("cnum"); // 修改后的数量
		
		// 2.调用业务逻辑进行更新
		CartService cartService = new CartServiceImpl();
		cartService.updateCar(cid, price, cnum);
		
		// 3.转发到展示的处理方法中
		return Constants.FORWARD + "/cart?method=show";
	}
	
	// 清空购物车
	public String clear(HttpServletRequest request, HttpServletResponse response) throws SQLException {
		// 1.获取uid
		String uid = request.getParameter("uid");
		
		// 2.调用业务逻辑进行清空购物车
		CartService cartService = new CartServiceImpl();
		cartService.clearCart(uid);
		
		// 3.转发到展示的处理方法中
		return Constants.FORWARD + "/cart?method=show";
	}
}
  1. 前端页面(对应cart.jsp 和cartSuccess.jsp的内容)

订单模块-提交订单并显示订单信息、用户确认后生成正式订单、用户查看历史订单

  1. DAO层(对应OrdersDaoImpl.java的内容)
package com.itqf.dao.impl;

import com.itqf.dao.OrdersDao;
import com.itqf.entity.Address;
import com.itqf.entity.Item;
import com.itqf.entity.Orders;
import com.itqf.entity.Product;
import com.itqf.utils.C3P0Utils;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;

import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class OrdersDaoImpl implements OrdersDao {
	@Override
	public void insertOrders(Orders orders) throws SQLException {
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		
		String sql = "insert into orders (o_id,a_id,u_id,o_count,o_state,o_time) " +
		"value(?,?,?,?,?,?);";
		
		queryRunner.update(sql, orders.getOid(), orders.getAid(), orders.getUid(), orders.getOcount()
		, orders.getOstate(), orders.getOtime());
	}
	
	@Override
	public void insertItems(List<Item> items) throws SQLException {
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		Object[][] params = new Object[items.size()][];
		String sql = "insert into item(o_id,p_id,i_count,i_num) value(?,?,?,?);";
		
		for (int i = 0; i < items.size(); i++) {
			Item item = items.get(i);
			params[i] = new Object[]{item.getOid(), item.getPid(), item.getIcount(), item.getInum()};
		}
		
		queryRunner.batch(sql, params);
	}
	
	@Override
	public List<Orders> selectOrdersByUid(int uid) throws InvocationTargetException, IllegalAccessException, SQLException {
		
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		
		String sql = "select o.o_id as oid,o.u_id as uid,o.a_id as aid," +
		"o.o_count as ocount,o.o_time as otime,o.o_state as ostate," +
		"a.a_name as aname,a.a_phone as aphone,a.a_detail as adetail, " +
		"a.a_state as astate from address a join orders o on a.a_id = o.a_id " +
		"where o.u_id = ?;";
		
		List<Map<String, Object>> list = queryRunner.query(sql, new MapListHandler(), uid);
		
		if (list == null) {
			return null;
		}
		
		List<Orders> ordersList = new ArrayList<>();
		for (Map<String, Object> map : list) {
			Orders orders = new Orders();
			Address address = new Address();
			
			BeanUtils.populate(orders, map);
			BeanUtils.populate(address, map);
			orders.setAddress(address);
			ordersList.add(orders);
		}
		
		return ordersList;
	}
	
	@Override
	public Orders selectOrdersByOid(String oid) throws SQLException, InvocationTargetException, IllegalAccessException {
		
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		
		String sql = "select o.o_id as oid,o.u_id as uid,o.a_id as aid," +
		"o.o_count as ocount,o.o_time as otime,o.o_state as ostate," +
		"a.a_name as aname,a.a_phone as aphone,a.a_detail as adetail, " +
		"a.a_state as astate from address a join orders o on a.a_id = o.a_id " +
		"where o.o_id = ?;";
		
		Map<String, Object> map = queryRunner.query(sql, new MapHandler(), oid);
		
		if (map == null) {
			return null;
		}
		
		Orders orders = new Orders();
		Address address = new Address();
		
		BeanUtils.populate(orders, map);
		BeanUtils.populate(address, map);
		orders.setAddress(address);
		
		return orders;
	}
	
	@Override
	public List<Item> selectItemsByOid(String oid) throws SQLException, InvocationTargetException, IllegalAccessException {
		
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		
		//订单项和商品
		String sql = "select p.p_id as pid, p.t_id as tid,p.p_name as pname,p.p_time as ptime ," +
		"p.p_image as pimage,p.p_state as pstate ,p.p_info as pinfo ,p.p_price as pprice," +
		"i.o_id as oid, i.i_id as iid ,i.i_count as icount,i.i_num as inum " +
		"from product p join item i on p.p_id = i.p_id  where i.o_id = ?;";
		
		List<Map<String, Object>> list = queryRunner.query(sql, new MapListHandler(), oid);
		
		if (list == null) {
			return null;
		}
		
		List<Item> items = new ArrayList<>();
		
		for (Map<String, Object> map : list) {
			Item item = new Item();
			Product product = new Product();
			BeanUtils.populate(product, map);
			BeanUtils.populate(item, map);
			item.setProduct(product);
			items.add(item);
		}
		return items;
	}
	
	@Override
	public void updateStateByOid(String oid) throws SQLException {
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		
		String sql = "update orders set o_state = ? where o_id = ?;";
		
		queryRunner.update(sql, 2, oid);
	}
	
}
  1. Service层(对应OrdersServiceImpl.java的内容)
package com.itqf.service.impl;

import com.itqf.dao.CartDao;
import com.itqf.dao.OrdersDao;
import com.itqf.dao.impl.CartDaoImpl;
import com.itqf.dao.impl.OrdersDaoImpl;
import com.itqf.entity.Cart;
import com.itqf.entity.Item;
import com.itqf.entity.Orders;
import com.itqf.service.OrdersService;
import com.itqf.utils.RandomUtils;

import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class OrdersServiceImpl implements OrdersService {
	@Override
	public void createOrder(String aid, String uid, String sum) throws SQLException, InvocationTargetException, IllegalAccessException {
		//1.创建一个订单对象进行保存
		Orders orders = new Orders();
		
		BigDecimal bsum = new BigDecimal(sum);
		
		String orderId = RandomUtils.createOrderId();
		orders.setOid(orderId);
		orders.setAid(Integer.parseInt(aid));
		orders.setUid(Integer.parseInt(uid));
		orders.setOtime(new Date());
		orders.setOcount(bsum);
		orders.setOstate(1); //未支付状态
		//2.保存订单
		OrdersDao ordersDao = new OrdersDaoImpl();
		ordersDao.insertOrders(orders);
		
		//3.将购物车转成订单项
		CartDao cartDao = new CartDaoImpl();
		List<Cart> carts = cartDao.selectCartsByUid(Integer.parseInt(uid));
		
		List<Item> items = new ArrayList<>();
		for (Cart cart : carts) {
			Item item = new Item();
			item.setOid(orderId);
			item.setPid(cart.getPid());
			item.setInum(cart.getCnum());
			item.setIcount(cart.getCcount());
			items.add(item);
		}
		
		//4.保存订单对应的订单项!
		ordersDao.insertItems(items);
		//5.清空购物车
		cartDao.deleteCartByUid(uid);
	}
	
	@Override
	public List<Orders> findOrders(int uid) throws SQLException, InvocationTargetException, IllegalAccessException {
		
		OrdersDao ordersDao = new OrdersDaoImpl();
		List<Orders> list = ordersDao.selectOrdersByUid(uid);
		return list;
	}
	
	@Override
	public Orders findOrder(String oid) throws SQLException, InvocationTargetException, IllegalAccessException {
		OrdersDao ordersDao = new OrdersDaoImpl();
		//1.oid查询订单和订单地址信息
		//订单和地址
		Orders orders = ordersDao.selectOrdersByOid(oid);
		//2.oid对应的对应的订单项和商品信息
		//订单项和商品信息
		List<Item> items = ordersDao.selectItemsByOid(oid);
		
		//3.订单项集合设置给订单对象
		orders.setItems(items);
		
		return orders;
	}
	
	@Override
	public void updateStateByOid(String oid) throws SQLException {
		OrdersDao ordersDao = new OrdersDaoImpl();
		ordersDao.updateStateByOid(oid);
	}
}
  1. Web层(对应OrdersController.java包的内容)
package com.itqf.controller;


import com.google.gson.Gson;
import com.itqf.entity.*;
import com.itqf.service.AddressService;
import com.itqf.service.CartService;
import com.itqf.service.OrdersService;
import com.itqf.service.impl.AddressServiceImpl;
import com.itqf.service.impl.CartServiceImpl;
import com.itqf.service.impl.OrdersServiceImpl;
import com.itqf.utils.Constants;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.List;

@WebServlet("/order")
public class OrdersController extends BaseServlet {
	
	public String preView(HttpServletRequest request, HttpServletResponse response) throws SQLException, InvocationTargetException, IllegalAccessException {
		
		//1.获取请求参数uid
		String uid = request.getParameter("uid");
		
		//2.调用业务逻辑 (地址,购物车)
		AddressService addressService = new AddressServiceImpl();
		List<Address> addressList = addressService.findAddress(Integer.parseInt(uid));
		
		CartService cartService = new CartServiceImpl();
		List<Cart> cartList = cartService.findAll(Integer.parseInt(uid));
		//3.放入共享域即可
		request.setAttribute("addressList", addressList);
		request.setAttribute("cartList", cartList);
		
		return Constants.FORWARD + "/order.jsp";
	}
	
	public String create(HttpServletRequest request, HttpServletResponse response) throws IllegalAccessException, SQLException, InvocationTargetException {
		
		//1.获取请求参数
		String aid = request.getParameter("aid");
		String uid = request.getParameter("uid");
		String sum = request.getParameter("sum");
		
		//2.调用业务逻辑生成订单
		
		OrdersService ordersService = new OrdersServiceImpl();
		ordersService.createOrder(aid, uid, sum);
		
		//3.转发到订单展示的方法
		
		return Constants.FORWARD + "order?method=show";
	}
	
	public String show(HttpServletRequest request, HttpServletResponse response) throws IllegalAccessException, SQLException, InvocationTargetException {
		HttpSession session = request.getSession();
		
		User user = (User) session.getAttribute("loginUser");
		
		if (user == null) {
			session.setAttribute("msg", "登录后可以查看订单!");
			return Constants.REDIRECT + "/login.jsp";
		}
		
		OrdersService ordersService = new OrdersServiceImpl();
		List<Orders> ordersList = ordersService.findOrders(user.getUid());
		request.setAttribute("ordersList", ordersList);
		return Constants.FORWARD + "/orderList.jsp";
	}
	
	public String detail(HttpServletRequest request, HttpServletResponse response) throws IllegalAccessException, SQLException, InvocationTargetException {
		
		String oid = request.getParameter("oid");
		
		OrdersService ordersService = new OrdersServiceImpl();
		Orders order = ordersService.findOrder(oid);
		request.setAttribute("order", order);
		return Constants.FORWARD + "/orderDetail.jsp";
	}
	
	
	public String success(HttpServletRequest request, HttpServletResponse response) throws SQLException {
		//1.获取请求参数
		String oid = request.getParameter("oid");
		String result = request.getParameter("result");
		
		System.out.println("oid" + oid);
		System.out.println("result" + result);
		
		Gson gson = new Gson();
		WeiXin weiXin = gson.fromJson(result, WeiXin.class);
		
		String result_code = weiXin.getResult().getResult_code();
		
		if (result_code != null && result_code.equals("SUCCESS")) {
			//支付成功
			//修改状态
			//订单列表页面
			OrdersService ordersService = new OrdersServiceImpl();
			ordersService.updateStateByOid(oid);
			return Constants.FORWARD + "/order?method=show";
		} else {
			//支付失败
			HttpSession session = request.getSession();
			session.setAttribute("msg", "订单:" + oid + " 支付失败!");
			//message.jsp页面
			return Constants.REDIRECT + "/message.jsp";
		}
	}
	
	
	
}
  1. 前端页面(对应order.jsp、orderList.jsp 和orderDetail.jsp的内容)

收货地址-管理收货地址(增删改查)

  1. DAO层(对应AddressDaoImpl.java的内容)
package com.itqf.dao.impl;

import com.itqf.dao.AddressDao;
import com.itqf.entity.Address;
import com.itqf.utils.C3P0Utils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import java.sql.SQLException;
import java.util.List;

public class AddressDaoImpl implements AddressDao {
	@Override
	public List<Address> selectAddressByUid(int uid) throws SQLException {
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		
		String sql = "select a_id as aid, u_id as uid,a_name as aname,a_phone " +
		"as aphone,a_detail as adetail ,a_state as astate from " +
		"address where u_id = ? order by a_state desc;";
		
		List<Address> list = queryRunner.query(sql, new BeanListHandler<Address>(Address.class), uid);
		return list;
	}
	
	@Override
	public void insertAddress(Address address) throws SQLException {
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		String sql = "insert into address (u_id,a_name,a_phone,a_detail,a_state) value(?,?,?,?,?)";
		
		queryRunner.update(sql, address.getUid(), address.getAname(),
		address.getAphone(), address.getAdetail(), address.getAstate());
	}
	
	@Override
	public void deleteAddressByAid(String aid) throws SQLException {
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		String sql = "delete from address where a_id = ?;";
		queryRunner.update(sql, aid);
	}
	
	@Override
	public void updateAddressToDefault(String aid) throws SQLException {
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		String sql = "update address set a_state = 1 where a_id = ?";
		queryRunner.update(sql, aid);
	}
	
	@Override
	public void updateAddressToCommons(String aid, int uid) throws SQLException {
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		String sql = "update address set a_state = 0 where a_id != ? and u_id = ?";
		queryRunner.update(sql, aid, uid);
	}
	
	@Override
	public void updateAddressByAid(Address address) throws SQLException {
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		String sql = "update address set a_state = ?,a_name=?,a_phone=?,a_detail = ? where a_id = ?;";
		queryRunner.update(sql, address.getAstate(), address.getAname(), address.getAphone(), address.getAdetail(), address.getAid());
		
	}
}
  1. Service层(对应AddressServiceImpl.java的内容)
package com.itqf.service.impl;

import com.itqf.dao.AddressDao;
import com.itqf.dao.impl.AddressDaoImpl;
import com.itqf.entity.Address;
import com.itqf.service.AddressService;

import java.sql.SQLException;
import java.util.List;

public class AddressServiceImpl implements AddressService {
	@Override
	public List<Address> findAddress(int uid) throws SQLException {
		AddressDao addressDao = new AddressDaoImpl();
		List<Address> list = addressDao.selectAddressByUid(uid);
		return list;
	}
	
	@Override
	public void saveAddress(Address address) throws SQLException {
		AddressDao addressDao = new AddressDaoImpl();
		addressDao.insertAddress(address);
	}
	
	@Override
	public void deleteAddress(String aid) throws SQLException {
		AddressDao addressDao = new AddressDaoImpl();
		addressDao.deleteAddressByAid(aid);
	}
	
	@Override
	public void setAddressToDefault(String aid, int uid) throws SQLException {
		AddressDao addressDao = new AddressDaoImpl();
		
		//1.将aid状态改为1 默认地址
		addressDao.updateAddressToDefault(aid);
		
		//2.将非aid状态改为0 非默认地址
		addressDao.updateAddressToCommons(aid, uid);
	}
	
	@Override
	public void updateAddress(Address address) throws SQLException {
		AddressDao addressDao = new AddressDaoImpl();
		addressDao.updateAddressByAid(address);
	}
}
  1. Web层(对应AddressController.java的内容)
package com.itqf.controller;


import com.itqf.entity.Address;
import com.itqf.entity.User;
import com.itqf.service.AddressService;
import com.itqf.service.impl.AddressServiceImpl;
import com.itqf.utils.Constants;
import org.apache.commons.beanutils.BeanUtils;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

@WebServlet("/address")
public class AddressController extends BaseServlet {
	
	
	public String show(HttpServletRequest request, HttpServletResponse response) throws SQLException {
		
		HttpSession session = request.getSession();
		User user  = (User) session.getAttribute("loginUser");
		if (user == null)
		{
			session.setAttribute("msg", "需要先登录!");
			return Constants.REDIRECT + "/login.jsp";
		}
		
		int uid = user.getUid();
		
		AddressService addressService = new AddressServiceImpl();
		List<Address> addresses = addressService.findAddress(uid);
		
		
		
		request.setAttribute("List", addresses);
		
		return Constants.FORWARD + "/self_info.jsp";
	}
	
	
	public String add(HttpServletRequest request,HttpServletResponse response) throws InvocationTargetException, IllegalAccessException, SQLException {
		
		//1.获取请求参数
		Map<String, String[]> map = request.getParameterMap();
		
		Address address = new Address();
		BeanUtils.populate(address,map);
		
		//2.调用业务逻辑进行地址添加
		AddressService addressService = new AddressServiceImpl();
		addressService.saveAddress(address);
		//3。转发到展示的方法
		return Constants.FORWARD + "/address?method=show";
	}
	
	public String delete(HttpServletRequest request,HttpServletResponse response) throws InvocationTargetException, IllegalAccessException, SQLException {
		
		//1.获取请求参数
		String aid = request.getParameter("aid");
		
		//2.调用业务逻辑进行地址添加
		AddressService addressService = new AddressServiceImpl();
		addressService.deleteAddress(aid);
		//3。转发到展示的方法
		return Constants.FORWARD + "/address?method=show";
	}
	
	public String setDefault(HttpServletRequest request,HttpServletResponse response) throws InvocationTargetException, IllegalAccessException, SQLException {
		
		//1.获取请求参数
		String aid = request.getParameter("aid");
		
		HttpSession session = request.getSession();
		User user  = (User) session.getAttribute("loginUser");
		
		if (user == null)
		{
			session.setAttribute("msg", "需要先登录!");
			return Constants.REDIRECT + "/login.jsp";
		}
		
		//2.调用业务逻辑进行地址添加
		AddressService addressService = new AddressServiceImpl();
		addressService.setAddressToDefault(aid,user.getUid());
		//3。转发到展示的方法
		return Constants.FORWARD + "/address?method=show";
	}
	
	public String update(HttpServletRequest request,HttpServletResponse response) throws InvocationTargetException, IllegalAccessException, SQLException {
		
		//1.获取请求参数
		Map<String, String[]> map = request.getParameterMap();
		
		Address address = new Address();
		BeanUtils.populate(address,map);
		
		//2.调用业务逻辑进行地址添加
		AddressService addressService = new AddressServiceImpl();
		addressService.updateAddress(address);
		//3。转发到展示的方法
		return Constants.FORWARD + "/address?method=show";
	}
}
  1. 前端页面(对应self_info.jsp的内容)

管理模块-增加、删除、修改、查找会员、订单、商品信息

  1. DAO层(对应AdminDaoImpl.java的内容)
package com.itqf.dao.impl;

import com.itqf.dao.AdminDao;
import com.itqf.entity.Cart;
import com.itqf.entity.Product;
import com.itqf.entity.User;
import com.itqf.utils.C3P0Utils;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;

import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class AdminDaoImpl implements AdminDao {
	@Override
	public void updateProduct(Product product) throws SQLException {
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		String sql = "INSERT INTO product (t_id, p_name, p_time, p_image, p_price, p_state, p_info) VALUES (?, ?, ?, ?, ?, ?, ?);";
		queryRunner.update(sql, product.getTid(), product.getPname(), product.getPtime(), product.getPimage(),
		product.getPprice(), product.getPstate(), product.getPinfo());
		
		
	}
	
	@Override
	public List<Product> selectAllGoods() throws SQLException {
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		String sql = "select p_id as pid,t_id as tid,p_name as pname,p_time as ptime ," +
		"p_image as pimage,p_state as pstate ,p_info as pinfo ,p_price as pprice " +
		"from product ;";
		List<Product> productList = queryRunner.query(sql, new BeanListHandler<>(Product.class));
		return productList;
	}
	
	@Override
	public List<User> selectAllUser() throws SQLException {
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		String sql = "select u_id as uid , u_name as username , u_password as upassword" +
		", u_sex as usex , u_status as ustatus , u_code as code , u_email as email " +
		", u_role as urole from user;";
		List<User> userList = queryRunner.query(sql, new BeanListHandler<>(User.class));
		return userList;
	}
	
	@Override
	public void deleteuserByuid(String uid) throws SQLException {
		QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
		String sql = "delete from user where u_id = ?;";
		queryRunner.update(sql, uid);
	}
}
  1. Service层(对应AdminServiceImpl.java的内容)
package com.itqf.service.impl;

import com.itqf.dao.AddressDao;
import com.itqf.dao.AdminDao;
import com.itqf.dao.impl.AddressDaoImpl;
import com.itqf.dao.impl.AdminDaoImpl;
import com.itqf.entity.Orders;
import com.itqf.entity.Product;
import com.itqf.entity.User;
import com.itqf.service.AdminService;

import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.List;

public class AdminServiceImpl implements AdminService {
	@Override
	public void updateProduct(Product product) throws SQLException {
		AdminDao addressDao = new AdminDaoImpl();
		addressDao.updateProduct(product);
	}
	
	@Override
	public List<Product> getAllGoods() throws SQLException, InvocationTargetException, IllegalAccessException {
		AdminDao addressDao = new AdminDaoImpl();
		List<Product> productList = addressDao.selectAllGoods();
		return productList;
	}
	
	@Override
	public List<User> getAllUser() throws SQLException {
		AdminDao addressDao = new AdminDaoImpl();
		List<User> users = addressDao.selectAllUser();
		return users;
	}
	
	@Override
	public void deleteuserByuid(String uid) throws SQLException {
		AdminDao addressDao = new AdminDaoImpl();
		addressDao.deleteuserByuid(uid);
	}
	
}
  1. Web层(对应AdminController.java的内容)
package com.itqf.controller;

import com.google.gson.Gson;
import com.itqf.entity.Product;
import com.itqf.entity.User;
import com.itqf.service.AdminService;
import com.itqf.service.UserService;
import com.itqf.service.impl.AdminServiceImpl;
import com.itqf.service.impl.UserServiceImpl;
import com.itqf.utils.Constants;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;


/**
* Admin模块的controller
*/
@MultipartConfig(
maxFileSize = 1024 * 1024 * 5, // 最大文件大小限制为5MB
maxRequestSize = 1024 * 1024 * 10 // 最大请求大小限制为10MB
)
@WebServlet("/admin/admin")
public class AdminController extends BaseServlet {
	
	public String login(HttpServletRequest request, HttpServletResponse response) throws SQLException {
		
		//1.获取请求参数(用户名,密码,验证码)
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		
		//3.调用业务逻辑判断账户密码
		UserService userService = new UserServiceImpl();
		User adminUser = userService.login(username, password);
		
		//4.响应
		//adminUser 等于null证明账号或者密码错误
		//adminUser 不为null 但是user的状态是未激活状态
		if (adminUser == null) {
			request.setAttribute("tip", "账号或者密码错误");
			return Constants.FORWARD + "/admin//login.jsp";
		}
		if (adminUser.getUstatus().equals(Constants.USER_NOT_ACTIVE)) {
			request.setAttribute("tip", "账号未激活!");
			return Constants.FORWARD + "/admin/login.jsp";
		}
		//        //把用户放在共享域session中
		HttpSession session = request.getSession();
		session.setAttribute("admin", adminUser);
		
		return Constants.REDIRECT + "/admin/admin.jsp";
		
	}
	
	
	/**
	* 添加商品
	*
	* @param request
	* @param response
	* @return
	* @throws InvocationTargetException
	* @throws IllegalAccessException
	* @throws SQLException
	*/
	public String addGoods(HttpServletRequest request, HttpServletResponse response) throws InvocationTargetException, IllegalAccessException, SQLException, ParseException, ServletException, IOException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Product product = new Product();
		// 获取单个表单字段的值
		product.setPname(request.getParameter("pname"));
		product.setTid(Integer.parseInt(request.getParameter("tid")));
		product.setPtime(sdf.parse(request.getParameter("ptime")));
		product.setPprice(new BigDecimal(request.getParameter("pprice")));
		product.setPstate(Integer.parseInt(request.getParameter("pstate")));
		product.setPinfo(request.getParameter("pinfo"));
		product.setPimage(request.getParameter("pimage"));
		System.out.println(product);
		
		//2.调用业务逻辑进行地址添加
		AdminService adminService = new AdminServiceImpl();
		adminService.updateProduct(product);
		
		return Constants.REDIRECT + "/admin/addGoods.jsp";
	}
	
	
	/**
	* 注销登录!清空数据!跳转到登录页面
	*
	* @param request
	* @param response
	* @return
	*/
	public String logOut(HttpServletRequest request, HttpServletResponse response) {
		//1.清空session中用户数据
		HttpSession session = request.getSession();
		session.removeAttribute("admin");
		
		//3.转发到登录页面
		request.setAttribute("tip", "注销登录成功");
		return Constants.FORWARD + "/admin/login.jsp";
	}
	
	/**
	* 查看商品
	*
	* @param request
	* @param response
	* @return
	*/
	public void showGoods(HttpServletRequest request, HttpServletResponse response) throws SQLException, InvocationTargetException, IllegalAccessException {
		//2.调用业务逻辑进行地址添加
		AdminService adminService = new AdminServiceImpl();
		List<Product> allGoods = adminService.getAllGoods();
		//把用户放在共享域session中
		HttpSession session = request.getSession();
		session.setAttribute("goodsList", allGoods);
	}
	
	/**
	* 会员信息管理
	*
	* @param request
	* @param response
	* @throws SQLException
	* @throws InvocationTargetException
	* @throws IllegalAccessException
	*/
	public void userList(HttpServletRequest request, HttpServletResponse response) throws SQLException, InvocationTargetException, IllegalAccessException, IOException {
		//2.调用业务逻辑进行地址添加
		AdminService adminService = new AdminServiceImpl();
		List<User> allGoods = adminService.getAllUser();
		// 将用户列表转换为JSON格式
		String json = new Gson().toJson(allGoods);
		// 将JSON数据写入响应
		response.setContentType("application/json");
		response.setCharacterEncoding("UTF-8");
		response.getWriter().write(json);
		
	}
	
	public void deleteUser(HttpServletRequest request, HttpServletResponse response) throws SQLException, InvocationTargetException, IllegalAccessException, IOException {
		//1.获取请求参数
		String uid = request.getParameter("uid");
		//2.调用业务逻辑进行地址添加
		AdminService adminService = new AdminServiceImpl();
		adminService.deleteuserByuid(uid);
		
		
	}
	
}
  1. 前端页面(对应/admin//login.jsp和/admin/admin.jsp的内容)

测试过程

用户模块-新用户注册、用户登录、用户退出

在这里插入图片描述

在这里插入图片描述

商品显示模块-分页显示所有商品、查看单个商品详细信息

在这里插入图片描述
在这里插入图片描述

购物车模块-加入商品到购物车、修改所购商品数量

在这里插入图片描述
在这里插入图片描述

订单模块-提交订单并显示订单信息、用户确认后生成正式订单、用户查看历史订单

在这里插入图片描述
在这里插入图片描述

支付模块-完成在线支付功能

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

收货地址-管理收货地址 (增删改查)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

管理模块-增加、删除、修改、查找会员、订单、商品信息

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

项目代码来源与下载

代码编写参考自博主:千锋教育_JavaWeb毕业设计<商城MyShop>_Java项目案例可上手

在博主的基础上增加了支付宝支付功能与后台管理功能
我的项目代码及报告的下载链接

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/338081.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《WebKit 技术内幕》之五(1): HTML解释器和DOM 模型

第五章 HTML 解释器和 DOM 模型 1.DOM 模型 1.1 DOM标准 DOM &#xff08;Document Object Model&#xff09;的全称是文档对象模型&#xff0c;它可以以一种独立于平台和语言的方式访问和修改一个文档的内容和结构。这里的文档可以是 HTML 文档、XML 文档或者 XHTML 文档。D…

MySQL 索引(下)

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;重拾MySQL-进阶篇 &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出现…

【STM32调试】寄存器调试不良问题记录持续版

STM32寄存器调试不良问题记录 低功耗管理NVIC&#xff08;内嵌的中断向量控制器&#xff09;EXTI&#xff08;外部中断/事件&#xff09; 记录一些stm32调试过程中&#xff1a;不易被理解、存在使用误区、不清不楚、是坑、使用常识等方面的一些记录。本记录只包含stm32的内核以…

UE5 C++学习笔记 常用宏的再次理解

1.随意创建一个类&#xff0c;他都有UCLASS()。GENERATED_BODY()这样的默认的宏。 UCLASS() 告知虚幻引擎生成类的反射数据。类必须派生自UObject. &#xff08;告诉引擎我是从远古大帝UObject中&#xff0c;继承而来&#xff0c;我们是一家人&#xff0c;只是我进化了其他功能…

动态规划——炮兵回城【集训笔记】

题目描述 游戏盘面是一个m行n列的方格矩阵&#xff0c;将每个方格用坐标表示&#xff0c;行坐标从下到上依次递增&#xff0c;列坐标从左至右依次递增&#xff0c;左下角方格的坐标为(1,1)&#xff0c;则右上角方格的坐标为(m,n)。 游戏结束盘上只剩下一枚炮兵没有回到城池中&a…

编曲学习:Cubase12导入Cubasis工程的方法!

Steinberg 发布 Cubasis 3 项目导入器&#xff0c;可将 Cubasis 的项目导入到 Cubase 使用https://m.midifan.com/news_body.php?id35635 我偶然看到这个文章&#xff0c;不过发现Cubase12默认好像没有这个选项&#xff0c;心想着要是移动端能和PC端同步&#xff0c;感觉会挺…

【网站项目】329网月科技公司门户网站

&#x1f64a;作者简介&#xff1a;多年一线开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

深入理解JavaScript箭头函数

&#x1f9d1;‍&#x1f393; 个人主页&#xff1a;《爱蹦跶的大A阿》 &#x1f525;当前正在更新专栏&#xff1a;《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​ ​ ✨ 前言 函数是JavaScript中非常重要的一个组成部分,可以封装代码逻辑,提高代…

x-cmd pkg | jq - 命令行 JSON 处理器

目录 简介首次用户功能特点类似工具进一步探索 简介 jq 是轻量级的 JSON 处理工具&#xff0c;由 Stephen Dolan 于 2012 年使用 C 语言开发。 它的功能极为强大&#xff0c;语法简洁&#xff0c;可以灵活高效地完成从 JSON 数据中提取特定字段、过滤和排序数据、执行复杂的转…

Transformer and Pretrain Language Models3-2

transformer structure注意力机制的各种变体 第二种变体&#xff1a; 如果两个向量的维度不一样&#xff0c;我们就需要在中间加上一个权重矩阵&#xff0c;来实现他们之间的相乘&#xff0c;然后最后得到一个标量 第三种变体&#xff1a; additive attention 它和前面的有…

顶顶通用户申请和安装 空号识别 模块流程

一、申请 空号识别 授权 打开网址&#xff1a;http://my.ddrj.com&#xff0c;注册并登录。 点击“我的授权” -> “申请授权” &#xff08;根据负责人的要求选择“在线”或是“离线”&#xff09;。 找到名称为空号识别的授权并点击“加号”图标打开授权&#xff0c;然…

JDK 动态代理(Spring AOP 的原理)(面试重点)

代理模式 也叫委托模式.定义&#xff1a;为其他对象提供⼀种代理以控制对这个对象的访问.它的作⽤就是通过提供⼀个代理类,让我们 在调⽤⽬标⽅法的时候,不再是直接对⽬标⽅法进⾏调⽤,⽽是通过代理类间接调⽤&#xff0c;在某些情况下,⼀个对象不适合或者不能直接引⽤另⼀个对…

geoserver pg_hba.conf 设置连接

geoserver pg_hba.conf 设置连接 在Postgre安装文件目录下的data文件夹中&#xff0c;修改pg_hba.conf文件&#xff0c;末尾添加重启postgresql的服务&#xff0c;应该就可以连了。

基于无锁循环队列的线程池的实现

目录 出处&#xff1a;B站码出名企路 应用场景 设计实现 等待策略模块 晚绑定 C 中的 override关键字 C中的 default 关键字 C中的 delete 关键字 C中的 explicit 关键字 C中 using 别名技巧 sleep 和 yield的区别 noexcept关键字 volatile关键字 无锁循环队列的…

第十二站(20天):C++泛型编程

模板 C提供了模板(template)编程的概念。所谓模板&#xff0c;实际上是建立一个通用函数或类&#xff0c; 其 类内部的类型和函数的形参类型不具体指定 &#xff0c;用一个虚拟的类型来代表。这种通用的方式称 为模板。 模板是泛型编程的基础, 泛型编程即以一种独立于任何特定…

JavaWeb-Listener

一、概念 Listener表示监听器&#xff0c;是JavaWeb三大组件&#xff08;Servlet&#xff0c;Filter&#xff0c;Listener&#xff09;之一&#xff0c;监听器的监听对象可以是application, session, request三个对象&#xff0c;监听的事件是这些对象的创建或销毁&#xff0c…

虚拟机将1.15版本的nginx推送到阿里云镜像仓库

1、docker images 2、docker login --usernamealiyun7279061146 registry.cn-shenzhen.aliyuncs.com 3、docker tag 53f3fd8007f7 registry.cn-shenzhen.aliyuncs.com/zhouwb/zhou:1.15 docker push registry.cn-shenzhen.aliyuncs.com/zhouwb/zhou:1.15

Linux第33步_TF-A移植的第1步_创建新的设备树

TF-A移植第1步就是创建新的设备树&#xff0c;并命名为“stm32mp157d-atk”。 和“TF-A移植”有关的知识点&#xff1a; 1)设备树英文名字叫做Device tree&#xff0c;用来描述板子硬件信息的&#xff0c;比如开发板上的 CPU有几个核 、每个CPU核主频是多少&#xff0c;IIC、…

线性代数:逆、转置、分块、多项式 矩阵公式总结

目录 逆矩阵、转置矩阵重要公式 公式 证明 矩阵分块 基本运算 分块的逆&#xff08;主副对角线分块对角阵的逆、主副对角线上下三角分块对角阵的逆&#xff09; 例 矩阵多项式 例 克拉默法则及逆矩阵求方程组 逆矩阵、转置矩阵重要公式 公式 证明 矩阵分块 基本运…

科技护航 智慧军休打通医养结合最后一公里

“小度小度&#xff0c;请帮我打电话给医生。” “好的&#xff0c;马上呼叫植物路军休所医生。” 2023年9月25日&#xff0c;常年独居、家住广西南宁市植物路军休所的军休干部程老&#xff0c;半夜突发疾病&#xff0c;让他想不到的是&#xff0c;这个常年伴他左右的“小度”…