仿小米商城-项目

仿小米商城

一、 软件理论

1、项目背景介绍

电子商务通常是指在全球各地广泛的商业贸易活动中,在因特网开放的网络环境下,基于浏览器/服务器应用方式,买卖双方不谋面地进行各种商贸活动,实现消费者的网上购物、商户之间的网上交易和在线电子支付以及各种商务活动、交易活动、金融活动和相关的综合服务活动的一种新型的商业运营模式。各国政府、学者、企业界人士根据自己所处的地位和对电子商务参与的角度和程度的不同,给出了许多不同的定义。

2、电子商务分类

① B2B

B2B = Business to Business。 商家(泛指企业)对商家的电子商务,即企业与企业之间通过互联网进行产品、服务及信息的交换。通俗的说法是指进行电子商务交易的供需双方都是商家(或企业、公司),他们使用 Internet 的技术或各种商务网络平台(如拓商网),完成商务交易的过程。过程包括:发布供求信息,订货及确认订货,支付过程,票据的签发、传送和接收,确定配送方案并监控配送过程等。

② B2C

B2C = Business to Customer。 B2C 模式是中国最早产生的电子商务模式,如今的 B2C 电子商务网站非常的多,比较大型的有天猫商城、京东商城、一号店、亚马逊、苏宁易购、国美在线等。

③ C2C

C2C = Consumer to Consumer。 C2C 同 B2B、B2C 一样,都是电子商务的几种模式之一。不同的是 C2C 是用户对用户的模式,C2C 商务平台就是通过为买卖双方提供一个在线交易平台,使卖方可以主动提供商品上网拍卖,而买方可以自行选择商品进行竞价。

④ B2M

B2M = Business to Manager。 B2M 是相对于 B2B、B2C、C2C 的电子商务模式而言,是一种全新的电子商务模式。而这种电子商务相对于以上三种有着本质的不同,其根本的区别在于目标客户群的性质不同,前三者的目标客户群都是作为一种消费者的身份出现,而 B2M 所针对的客户群是该企业或者该产品的销售者或者为其工作者,而不是最终消费者。

⑤ B2A

B2A(B2G) = Business to Government。 B2G 模式是企业与政府管理部门之间的电子商务,如政府采购,海关报税的平台,国税局和地税局报税的平台等。

⑥ O2O

O2O = Online to Offline。 O2O 是新兴起的一种电子商务新商业模式,即将线下商务的机会与互联网结合在了一起,让互联网成为线下交易的前台。这样线下服务就可以用线上来揽客,消费者可以用线上来筛选服务,还有成交可以在线结算,很快达到规模。特点是:推广效果可查,每笔交易可跟踪。如美乐乐的 O2O 模式为例,其通过搜索引擎和社交平台建立海量网站入口,将在网络的一批家居网购消费者吸引到美乐乐家居网,进而引流到当地的美乐乐体验馆。线下体验馆则承担产品展示与体验以及部分的售后服务功能。

⑦ B2B2C

第一个Business,并不仅仅局限于品牌供应商、影视制作公司和图书出版商,任何的商品供应商或服务供应商都能成为第一个Business;第二B是B2B2C模式的电子商务企业,通过统一的经营管理对商品和服务、消费者终端同时进行整合,是广大供应商和消费者之间的桥梁,为供应商和消费者提供优质的服务,是互联网电子商务服务供应商。C表示消费者,在第二个B构建的统一电子商务平台购物的消费者

 

3、常见的软件类型

① 传统项目

OA:办公自动化系统

CRM:客户关系管理系统

ERP:综合的企业解决方案

② 互联网项目

电商:京东、淘宝

视频: 优酷、土豆、腾讯视频、爱奇艺

③ 门户网站(综合咨询类)

门户(portal),原意是指正门、入口,现多用于互联网的门户网站和企业应用系统的门户系统。门户网站,也是一个被称为链接页面,提出一个统一的信息的方式从不同的来源研究。所谓门户网站,是指通向某类综合性互联网信息资源并提供有关信息服务的应用系统

例如:163、搜狐、新浪

④ 企业网站:

 

4、团队介绍

① 什么是团队

团队就是一群人合作做一件事情

◦ 每个人分担不同的角色职责,并有独特的贡献 - 分工

◦ 有沟通与合作,并能够产生高成果 - 合作

◦ 有明确的、共同的目标

② 小公司开发团队

image-20220419233338921

③ 中型公司开发团队

image-20220419233345313

 

④ 微软公司开发团队

image-20220419233455893

 

5、软件开发流程

① 项目立项

就是确定做一件事情,软件服务商从技术/经济/社会因素等综合评估项目的可行性,并制定开发计划。

② 需求分析

需求规格说明书、原型(Axure、photo),软件开发周期,报价

常见软件开发形式:

软件定制(项目)

甲方:软件公司

乙方:餐饮公司,需要一套软件找到甲方公司

 

软件产品(产品)

甲方:软件公司自己开发一套软件产品,推出市场

 

软件外包(项目)

A: 软件公司 (软件人才)

B: 需要开发一套系统,从A公司借调人才,项目开发完,再归还给A公司

 

③ 项目设计

(概要设计、详细设计)----页面原型(HTML)、数据库设计(SQL脚本)、设计文档

④ 编码阶段

(后端编码,前端编码)—文档:编码规范

⑤ 测试阶段

测试用例

⑥ 上线运维

软件使用说明书

6 软件生命周期模型

① 瀑布模型

瀑布模型核心思想是按工序将问题化简,将功能的实现与设计分开,便于分工协作,即采用结构化的分析与设计方法将逻辑实现与物理实现分开。将软件生命周期划分为制定计划、需求分析、软件设计、程序编写、软件测试和运行维护等六个基本活动,并且规定了它们自上而下、相互衔接的固定次序,如同瀑布流水,逐级下落。

优点:

1为项目提供了按阶段划分的检查点。

2当前一阶段完成后,您只需要去关注后续阶段。

 

缺点:

1)各个阶段的划分完全固定,阶段之间产生大量的文档,极大地增加了工作量。

2)由于开发模型是线性的,用户只有等到整个过程的末期才能见到开发成果,从而增加了开发风险。

3)通过过多的强制完成日期和里程碑来跟踪各个项目阶段。

4)瀑布模型的突出缺点是不适应用户需求的变化。

 

② 迭代模型

在现代过程方法XP(eXtreme Programming,极限编程)、RUP无一例外地都推荐、主张采用能显著减少风险的迭代模型。美国国防部原本提倡瀑布过程和观点,在发现那么多采用了瀑布模型的失败的项目之后,不但放弃了对它的要求,而且从1994年的报告开始,积极地鼓励采用更加现代化的迭代模型来取代瀑布模型做法。

开发迭代是一次完整地经过所有工作流程的过程:需求分析、设计、实施和测试工作流程,每一次的迭代都会产生一个可以发布的产品,这个产品是最终产品的一个子集。

 

优点:

与传统的瀑布模型相比较,迭代过程具有以下优点:

1)降低了在一个增量上的开支风险。如果开发人员重复某个迭代,那么损失只是这一个开发有误的迭代的花费。

2)降低了产品无法按照既定进度进入市场的风险。通过在开发早期就确定风险,可以尽早来解决而不至于在开发后期匆匆忙忙。

3)加快了整个开发工作的进度。因为开发人员清楚问题的焦点所在,他们的工作会更有效率。

4)由于用户的需求并不能在一开始就作出完全的界定,它们通常是在后续阶段中不断细化的。因此,迭代过程这种模式使适应需求的变化会更容易些。

 

缺点:

对软件研发团队素质要求高,必须对业务非常熟悉。

 

二、项目介绍

1、介绍

仿小米商城提供了网上交易洽谈的平台,协调整合了信息流、货物流、资金流等等重要场所。将传统的商务流程电子化,数字化;大量的减少了人力,物力,降低了成本;突破了时间和空间的限制,大大提高了工作效率,使得交易活动可以在任何地点、任何时间进行。

2、开发环境选型

 开发环境生产环境
操作系统 Windows 7/10 Centos 6.8
开发工具 Idea、Eclipse、MyEclipse  
数据库 MySQL5.7 MySQL5.7
Web服务器 Tomcat8.0/8.5 Tomcat8.0/8.5
浏览器 Chrome/FireFox/IE  

3、技术选型

编号工具版本备注
1 Servlet、Filter、Jsp、html、EL、JSTL Servlet3.1 JSP2.3 Web
2 DBUtils 1.6 dao
3 junit 4.12 单元测试
4 Druid 1.5 连接池
5 jQuery 1.12.4  
6 Bootstrap 3.3.7  
7 mail   发送邮件

 

三、环境搭建

1、数据库环境

创建数据库

CREATE DATABASE db_shopping;

 

2、idea创建web项目

image-20220421094736701

3、导入前端资料

在资料 --- 前端资料 -- 复制到idea项目的web目录下;如出现需要替换的提示,直接全部替换

image-20220421094912619

4、导入jar包

在资料 -- jar包中找到jar包; 复制到 idea项目 web -- WEB-INF --- lib中

image-20220421095105620

如图所示:

image-20220421095215177

导入jar包

image-20220421100933984

效果如下:

image-20220421101011880

5、编写数据源工具类

database.properties

jdbc.url=jdbc:mysql://localhost:3306/db_shopping?characterEncoding=utf8
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.username=root
jdbc.password=123456
jdbc.initialSize=5
jdbc.maxActive=20
jdbc.maxWait=60000
jdbc.minIdle=10

DataSourceUtils.java

package com.qf.utils;

import com.alibaba.druid.pool.DruidDataSource;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 * @author 千锋教育
 * @Company http://www.mobiletrain.org/
 * @Version 1.0
 */
public class DataSourceUtils {
    private static DruidDataSource dataSource = new DruidDataSource();
    //静态代码块: 只执行一次
    static {
        //读取properties属性值
        Properties prop = new Properties();
        //加载属性文件, 获取输入流对象
        InputStream inputStream = DataSourceUtils.class.getClassLoader().getResourceAsStream("database.properties");
        try {
            prop.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("加载database.properties属性文件失败!!");
        }

        dataSource.setUrl(prop.getProperty("jdbc.url"));
        dataSource.setUsername(prop.getProperty("jdbc.username"));
        dataSource.setPassword(prop.getProperty("jdbc.password"));
        dataSource.setDriverClassName(prop.getProperty("jdbc.driverClassName"));
    }

    //返回连接池
    public static DataSource getDataSource() {
        return dataSource;
    }

    //返回连接对象
    public static Connection getConnection() {
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("获取连接对象失败");
            return null;
        }
    }

    /**
     * 测试
     * @param args
     */
    public static void main(String[] args) {
        Connection conn = getConnection();
        System.out.println(conn);
    }

}

 

6、抽取公共servlet

package com.qf.web.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;

/**
 * 抽取servlet: servlet 共同的部分
 * 
 * @author 千锋教育
 * @Company http://www.mobiletrain.org/
 * @Version 1.0
 */
public class BaseServlet extends javax.servlet.http.HttpServlet {

    @Override
    protected void doGet(jav3ax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(javax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        //1. 获取参数中的method = add
        String param = req.getParameter("method");
        //2. 获取要执行的方法对象(反射)
        try {
            //通过反射获取 要执行的方法
            Method method = this.getClass().getMethod(param, HttpServletRequest.class, HttpServletResponse.class);
            //执行方法(result 就是方法的返回值)
            //如果method 是void , 则返回null
            Object result = method.invoke(this, req, resp);
            if(result == null) {
                //认为前端是ajax
            }
            //否则需要请求转发与重定向
            else {
                String res = result.toString();
                //如果是重定向: 约定前缀为 redirect
                if(res.startsWith("redirect:")){
                    //对res进行切割
                    String[] arr = res.split(":");
                    if(arr!= null && arr.length > 1){
                        resp.sendRedirect(arr[1]);
                    }
                }
                //如果是请求转发, 约定前缀为 forward
                else {
                    //对res进行切割
                    String[] arr = res.split(":");
                    if(arr!= null && arr.length > 1){
                        req.getRequestDispatcher(arr[1]).forward(req, resp);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("调用方法失败!!!");
        }

    }
}

 

四、功能开发

1、用户功能

① 注册

业务分析

  1. (课上实现)输入用户名,失去焦点后,校验用户名是否存在,如果存在,则不能注册

  2. 密码失去焦点后,校验是否为空; 校验两次输入的密码是否相同

  3. 校验邮箱是否已经被注册

  4. 点击注册按钮,注册用户。

页面

$(function(){
		$("#username").blur(function(){
       //校验用户名不能为空
			 if(this.value == null || this.value.length == 0) {
				 $("#usernameMsg").html("用户名不能为空").css("color","red");
				 $("#registerBtn").attr("disabled",true);
			 }else {
         //校验用户名是否存在,如存在,则不能注册。
				 //使用ajax 做username 的异步验证 checkUsername?username=xxxx
				 $.get("userservlet?method=checkUserName","username="+this.value,function(data){
					 // alert(data);
					 if(data == '0'){
						 $("#usernameMsg").html("用户名不能为空").css("color","red");
						 $("#registerBtn").attr("disabled",true);
					 } else if(data=="1"){
             //如果用户名已存在,显示提示信息。 并设置按钮不可使用
						 $("#usernameMsg").html("用户名已经存在").css("color","red");
						 $("#registerBtn").attr("disabled",true);
					 }else{
						 $("#usernameMsg").html("用户名可用").css("color","green");
						 $("#registerBtn").removeAttr("disabled");
					 }
				 })
			 }

		});
  
  
  <!-- 注册的表单 -->
  <!-- action:表单提交路径  -->  
  <form id="form1" class="form-horizontal" action="userservlet?method=register" method="post">

					<div class="form-group">
						<label class="col-sm-2 control-label">用户名</label>
						<div class="col-sm-8" style="width: 40%">
							<input type="text" id="username" name="username" class="form-control col-sm-10"
								placeholder="Username" />
						</div>
						<div class="col-sm-2">
						<p class="text-danger"><span class="help-block " id="usernameMsg"></span></p>
						</div>
					</div>
					<div class="form-group">
						<label class="col-sm-2 control-label">密码</label>
						<div class="col-sm-8" style="width: 40%">
							<input type="password" name="password" id="password"
								class="form-control col-sm-10" placeholder="Password"  />
						</div>
						<div class="col-sm-2">
						<p class="text-danger"><span  id="helpBlock" class="help-block ">请输入6位以上字符</span></p>
						</div>
					</div>
					<div class="form-group">
						<label class="col-sm-2 control-label">确认密码</label>
						<div class="col-sm-8" style="width: 40%">
							<input id="repassword" type="password" name="repassword" class="form-control col-sm-10"
								placeholder="Password Again" />
						</div>
						<div class="col-sm-2">
						<p class="text-danger"><span  id="repasswordMsg" class="help-block ">两次密码要输入一致哦</span></p>
						</div>
					</div>

					<div class="form-group">
						<label class="col-sm-2 control-label">邮箱</label>
						<div class="col-sm-8" style="width: 40%">
							<input type="email" name="email" class="form-control col-sm-10"
								placeholder="Email" />
						</div>
						<div class="col-sm-2">
						<p class="text-danger"><span id="helpBlock" class="help-block ">填写正确邮箱格式</span></p>
						</div>
					</div>
					<div class="form-group">
						<label class="col-sm-2 control-label">性别</label>
						<div class="col-sm-8" style="width: 40%">
							<label class="radio-inline"> <input type="radio"
								name="gender" value="男" checked="checked"> 男
							</label> <label class="radio-inline"> <input type="radio"
								name="gender" value="女"> 女
							</label>
						</div>
						<div class="col-sm-2">
						<p class="text-danger"><span id="helpBlock" class="help-block ">你是帅哥 还是美女</span></p>
						</div>
					</div>
					<hr>
					<div class="form-group">
						<div class="col-sm-7 col-sm-push-2">
							<input id="registerBtn" type="submit" value="注册" class="btn btn-primary  btn-lg" style="width: 200px;" disabled/> &nbsp; &nbsp;
							<input type="reset" value="重置" class="btn btn-default  btn-lg" style="width: 200px;"  />
						</div>
					</div>
					<div class="text-center" style="color:red">${registerMsg}</div>
				</form>

serlvet

/**
     * 注册功能
     * 1. 获取前端请求的参数
     * 2. 保存到数据库
     * 3. 响应前端(
     *      注册成功,跳转到登录页面
     *      注册失败, 跳转到注册页面
     * )
     * @param req
     * @param resp
     * @return
     */
    public String register(HttpServletRequest req, HttpServletResponse resp){
        //获取 请求参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String email = req.getParameter("email");
        String gender = req.getParameter("gender");

        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        user.setEmail(email);
        user.setGender(gender);

        // 调用service ,保存到数据库
        boolean isSuccess = userService.register(user);
        //如果注册成功,跳转登录页面
        if(isSuccess) {
            return "redirect:/login.jsp";
        } else {
            //否则,跳转到注册页面
            return "redirect:/register.jsp";
        }

    }

    /**
     * 校验用户名 是否存在
     *  1. 获取 username 参数
     *  2. 如果username为空,则返回 0
     *  3. 查询数据库, 如果存在,返回1
     *  4. 如果不存在,返回2
     * @param req
     * @param resp
     */
    public void checkUserName(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //获取参数
        String username = req.getParameter("username");
        PrintWriter writer = resp.getWriter();
        //判断 如果为空,返回0
        if(StringUtils.isEmpty(username)) {
            writer.write("0");
        } else {
            //username 不为空, 则根据username查询数据库1
            User user  = userService.findByUsername(username);
            if(user == null) {
                //如果username 在数据库不存在,则返回2
                writer.write("2");
            }else {
                //如果username 在数据库存在,则返回1
                writer.write("1");
            }
        }


    }

service接口

/**
 * @author 千锋教育
 * @Company http://www.mobiletrain.org/
 * @Version 1.0
 */
public interface UserService {
    /**
     * 检测用户名是否存在
     * @param username
     * @return
     */
    User findByUsername(String username);

    /**
     * 注册
     * 
     * @param username
     * @param password
     * @param email
     * @param gender
     * @return
     */
    boolean register(User user);
}

service实现类

public class UserServiceImpl implements UserService {    
		@Override
    public User findByUsername(String username) {
        return dao.findByUsername(username);
    }

    /**
     * 注册: 添加数据到数据库
     *  页面: 完善  user对象
     * @param user
     * @return
     */
    @Override
    public boolean register(User user) {
        //设置为 已激活
        user.setFlag(1);
        //设置 为管理员
        user.setRole(0);
        dao.add(user);
        return true;
    }
  
}

dao接口

/**
 * @author 千锋教育
 * @Company http://www.mobiletrain.org/
 * @Version 1.0
 */
public interface UserDao  {
    User findByUsername(String username);

    void add(User user);

}

dao实现类

/**
 * @author 千锋教育
 * @Company http://www.mobiletrain.org/
 * @Version 1.0
 */
public class UserDaoImpl implements UserDao {

    @Override
    public long selectCountByUsername(String username) {
        QueryRunner qf = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select count(0) from tb_user where username = ? and role=0";
        try {
            Long count = (Long) qf.query(sql, new ScalarHandler(), username);
            return count;
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("检查用户名是否存在失败!!!");
        }
        return 0;
    }

    @Override
    public int insert(User user) {
        QueryRunner qf = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "insert into tb_user values(null ,?,md5(?),?,?,?,?,?)";
        try {
            int count = qf.update(sql, user.getUsername(),
                    user.getPassword(), user.getEmail(), user.getGender(), user.getFlag(), 1, "");
            return count;
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("注册用户失败!!!");
        }
        return  0;

    }
}

 

② 登录

页面

<form  method="post" action="userservlet?method=login" class="form center" id="userLogin" >
		<div class="login">
			<div class="login_center">
				<div class="login_top">
					<div class="left fl">会员登录</div>
					<div class="right fr">您还不是我们的会员?<a href="${pageContext.request.contextPath }/register.jsp" target="_self">立即注册</a></div>
					<div class="clear"></div>
					<div class="xian center"></div>
				</div>
				<div class="login_main center">
					<div class="username">
						<div class="left fl">用户名:&nbsp;</div>
						<div class="right fl">
						<input class="shurukuang" type="text" name="username" id="username"  placeholder="请输入你的用户名"/>
						<label id="nameMsg"></label>
						</div>
					</div>
					<div class="username">
						<div class="left fl">密&nbsp;&nbsp;&nbsp;&nbsp;码:&nbsp;</div>
						<div class="right fl">
						<input class="shurukuang" type="password" name="password"  id="pwd"  placeholder="请输入你的密码"/>	
						</div>
					</div>
					<div class="username">
						<div class="left fl">验证码:&nbsp;</div>
						<div class="right fl"><input class="yanzhengma" id="vcode" type="text" placeholder="验证码"/>
						<img  id="pagecode" src="userservlet?method=code"><label id="checkMsg"></label></div>					
					</div>
					<div class="username">
						<div class="left fl">&nbsp;&nbsp;&nbsp;&nbsp;</div>
						<div class="right fl"><label id="checkMsg"></label></div>
					</div>
					<div class="username">
						<input id="autoLogin" name="auto" type="checkbox" />&nbsp;&nbsp;两周以内自动登录
						<span id="autoLoginMsg"></span>
					</div>
					<div class="login_submit">
						<input class="submit" type="submit" name="submit" value="立即登录" id="btn" disabled >
					</div>
					<span style="color:red">${msg}</span>
				</div>	
			</div>
		</div>

serlvet

/**
     * 登录功能
     * @param req
     * @param resp
     * @throws Exception
     */
    public String login(HttpServletRequest req, HttpServletResponse resp) throws Exception{
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        //是否自动登录
        String auto = req.getParameter("auto");

        // 根据用户名和密码查询用户对象
        User user = userService.findByUserAndPwd(username, password);
        if(user == null){
            //如果user为null,则登录失败
            return "redirect:/login.jsp";
        }else {
            //否则登录成功
            //保存登录状态
            req.getSession().setAttribute("user",  user);

            //保存登录状态到cookie中
            if("on".equalsIgnoreCase(auto)) {
                //对 用户名和密码进行 数据转换
                String encode = URLEncoder.encode(username + "#" + password, "utf-8");
                //创建cookie对象
                Cookie cookie = new Cookie("user", encode);

                cookie.setDomain("localhost"); //设置域名
                cookie.setPath("/"); //设置 在任意路径下都可以获取cookie
                cookie.setMaxAge(14 * 24 * 60 * 60);  //设置有效期为两周
                resp.addCookie(cookie);
            }

            //跳转到首页
            return "redirect:/index.jsp";
        }


    }

    /**
     * 校验验证码
     * @param req
     * @param resp
     * @throws Exception
     */
    public void checkCode(HttpServletRequest req, HttpServletResponse resp) throws Exception{
        //获取用户输入的验证码
        String inputCode = req.getParameter("code");
        PrintWriter writer = resp.getWriter();
        //从session中获取验证码
        Object codeObj = req.getSession().getAttribute("code");
        if(codeObj == null) {
            writer.write("1");
        }else {
            String code = (String) codeObj;
            if(code.equalsIgnoreCase(inputCode)){
                writer.write("0");
            }else {
                writer.write("1");
            }
        }

    }


    /**
     * 获取验证码
     * @param req
     * @param resp
     * @return
     */
    public void code(HttpServletRequest req, HttpServletResponse resp) throws Exception{

        //创建验证码对象
        ValidateCode validateCode = new ValidateCode(111, 37, 2, 20);

        //在session中存储验证码
        HttpSession session = req.getSession();
        session.setAttribute("code", validateCode.getCode());


        //把验证码 输出到  响应对象的输出流(前端)
        validateCode.write(resp.getOutputStream());
    }

service接口

User findByUserAndPwd(String username, String password);

service实现类

@Override
    public User findByUserAndPwd(String username, String password) {
        return dao.findUserAndPwd(username ,password);
    }

dao接口

User findUserAndPwd(String username, String password);

dao实现类

@Override
    public User findUserAndPwd(String username, String password) {
        QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select * from tb_user where username  = ? and password = md5(?)";
        try {
            User user = qr.query(sql, new BeanHandler<>(User.class), username, password);
            return user;
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("UserDao:根据用户名查询用户失败");
        } finally {
            //释放资源(关闭连接)
        }
        return null;
    }

 

③ 自动登录

1.登录成功后,存储账号和密码 到 cookie中

2.访问网站时,判断是否登录了, 如果没有登录, 则从cookie中获取用户名和密码; 然后进行校验, 如果用户名密码正确,自动登录成功。否则登录失败。

过滤器

package com.qf.xiaomi.web.filter;

import com.qf.xiaomi.pojo.User;
import com.qf.xiaomi.service.UserService;
import com.qf.xiaomi.service.impl.UserServiceImpl;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.net.URLDecoder;

/**
 *
 * 自动登录 过滤器
 *  1. 先判断是否登录了, 如果登录了,直接放行
 *  2. 如果未登录,实现自动登录
 *      2.1 从cookie中获取账号和密码信息
 *      2.2 校验账户和密码是否正确
 *      2.3 如果正确,保存登录状态到session中, 再放行
 *      2.4 如果错误,直接放行
 * @author 千锋教育
 * @Company http://www.mobiletrain.org/
 * @Version 1.0
 */
@WebFilter("/*")
public class AutoLoginFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //转换为 子类对象
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        //获取登录状态
        HttpSession session = req.getSession();
        Object user = session.getAttribute("user");
        //如果用户不为空,(说明已登录)则放行
        if(user != null){
            //放行
            filterChain.doFilter(req, resp);
            return;
        }

        //实现自动登录过程
        //从cookie中获取账户信息
        Cookie[] cookies = req.getCookies();
        for (Cookie cookie : cookies) {
            String name = cookie.getName();

            if("user".equalsIgnoreCase(name)) {
                String value = cookie.getValue();
                //解码
                String decode = URLDecoder.decode(value, "utf-8");
                //切割
                String[] split = decode.split("#");
                String username = split[0];
                String password = split[1];
                //执行登录操作
                UserService service = new UserServiceImpl();
                User userDb = service.findByUserAndPwd(username, password);
                if(userDb != null) {
                    //如果为不为空,则登录成功
                    session.setAttribute("user", userDb);
                }
                filterChain.doFilter(req, resp);

            }
        }


    }

    @Override
    public void destroy() {

    }
}

 

④ 退出

servlet

/**
     * 注销
     * @param req
     * @param resp
     * @throws Exception
     */
    public String logOut(HttpServletRequest req, HttpServletResponse resp) throws Exception{
        //清空session
        req.getSession().invalidate();

        //跳转到登录页面
        return "redirect:/login.jsp";
    }

 

2、商品分类功能

① 分类查询

页面

serlvet

package com.qf.xiaomi.web.servlet;

import com.alibaba.fastjson.JSON;
import com.qf.xiaomi.pojo.GoodsType;
import com.qf.xiaomi.service.GoodsTypeService;
import com.qf.xiaomi.service.impl.GoodsTypeServiceImpl;
import com.qf.xiaomi.web.base.BaseServlet;

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.util.List;

/**
 * @author 千锋教育
 * @Company http://www.mobiletrain.org/
 * @Version 1.0
 */
@WebServlet("/goodstypeservlet")
public class GoodsTypeServlet extends BaseServlet {

    GoodsTypeService service = new GoodsTypeServiceImpl();

    /**
     * 获取商品 一级分类 列表
     * @param req
     * @param resp
     */
    public void goodstypelist(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //查询一级商品分类列表
        List<GoodsType> goodsTypeList =  service.getGoodsTypeL1();
        //响应前端
        resp.setCharacterEncoding("utf-8");
        PrintWriter writer = resp.getWriter();
        //把列表数据转换为 json数据
        String json = JSON.toJSONString(goodsTypeList);
        writer.write(json);
    }

}

service接口

/**
 * @author 千锋教育
 * @Company http://www.mobiletrain.org/
 * @Version 1.0
 */
public interface GoodsTypeService {
    List<GoodsType> getGoodsTypeL1();
}

service实现类

public class GoodsTypeServiceImpl implements GoodsTypeService {

    GoodsTypeDao dao = new GoodsTypeDaoImpl();

    @Override
    public List<GoodsType> getGoodsTypeL1() {
        return dao.getGoodsTypeL1();
    }
}

dao接口

public interface GoodsTypeDao {
    List<GoodsType> getGoodsTypeL1();
}

dao实现类

public class GoodsTypeDaoImpl implements GoodsTypeDao {
    @Override
    public List<GoodsType> getGoodsTypeL1() {
        QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select * from tb_goods_type where level = 1";
        try {
            List<GoodsType> goodsTypeList = qr.query(sql, new BeanListHandler<>(GoodsType.class));
            return goodsTypeList;
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("查询商品分类失败");
        }


        return null;
    }
}

 

3、商品功能

①商品分页展示

页面

<script type="text/javascript">
	$(document).ready(function(){
		$.ajax({
			url:"${pageContext.request.contextPath}/goodstypeservlet?method=goodstypelist",
			type:"GET",
			success:function(data){
				for(var i in data){
					var a = $("<a href='${pageContext.request.contextPath}/goodsservlet?method=getGoodsListByTypeId&typeId="+data[i].id+"'>"+data[i].name+"</a>");
					$("#goodsType").append(a);
					
				}
			},
			dataType:"json",
			error:function(){
				alert("失败");
			}
		})
	})
</script>

 

serlvet

@WebServlet("/goodsservlet")
public class GoodsServlet extends BaseServlet {

    GoodsService service = new GoodsServiceImpl();



    /**
     * 根据商品分类id 查询 商品列表(实现分页效果)
     * @param req
     * @param resp
     * @return
     * @throws Exception
     */
    public String getGoodsListByTypeId(HttpServletRequest req, HttpServletResponse resp) throws Exception{
        //获取 分类id
        int typeId = Integer.parseInt(req.getParameter("typeId"));
        //获取 每页条数
        int pageSize = 6;
        String pageSizeStr = req.getParameter("pageSize");
        if(pageSizeStr != null){
            pageSize = Integer.parseInt(pageSizeStr);
        }

        //获取当前页
        int pageNum = 1;
        String pageNumStr = req.getParameter("pageNum");
        if(pageNumStr != null){
            pageNum = Integer.parseInt(pageNumStr);
        }


        //分页查询数据
        PageBean<Goods> pageBean  = service.findGoodsListByTypeIdPage(typeId, pageSize, pageNum);

        //把分页数据存储到请求域
        req.setAttribute("pageBean", pageBean);


        //响应前端
        return "forward:/goodsList.jsp";

    }
}

service接口

public interface GoodsService  {
    PageBean<Goods> findGoodsListByTypeIdPage(int typeId, int pageSize, int pageNum);
}

service实现类

package com.qf.xiaomi.service.impl;

import com.qf.xiaomi.dao.GoodsDao;
import com.qf.xiaomi.dao.GoodsTypeDao;
import com.qf.xiaomi.dao.impl.GoodsDaoImpl;
import com.qf.xiaomi.dao.impl.GoodsTypeDaoImpl;
import com.qf.xiaomi.entity.PageBean;
import com.qf.xiaomi.pojo.Goods;
import com.qf.xiaomi.pojo.GoodsType;
import com.qf.xiaomi.service.GoodsService;

import java.util.List;

/**
 * @author 千锋教育
 * @Company http://www.mobiletrain.org/
 * @Version 1.0
 */
public class GoodsServiceImpl implements GoodsService {

    GoodsDao dao = new GoodsDaoImpl();

    @Override
    public PageBean<Goods> findGoodsListByTypeIdPage(int typeId, int pageSize, int pageNum) {
        //封装PageBean
        PageBean<Goods> pageBean = new PageBean();
        //当前页
        pageBean.setPageNum(pageNum);
        //每页条数
        pageBean.setPageSize(pageSize);
        //起始页
        pageBean.setStartPage(1);

        long totalCount = dao.getTotalCount(typeId);
        //总条数
        pageBean.setTotalCount(totalCount);


        //设置列表数据  limit m,n;
        int startIndex = pageSize * (pageNum - 1);
        List<Goods> data = dao.getData(typeId, startIndex, pageSize );
        pageBean.setData(data);

        return pageBean;
    }


}

dao接口

public interface GoodsDao {
    long getTotalCount(int typeId);

    List<Goods> getData(int typeId, int startIndex, int pageSize);
}

dao实现类

public class GoodsDaoImpl implements GoodsDao {
    @Override
    public long getTotalCount(int typeId) {
        QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select count(1) from tb_goods where typeId = ?";

        try {
            long count = (long) qr.query(sql, new ScalarHandler(), typeId);
            return count;
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("查询商品总条数失败");
        }
        return 0;
    }

    @Override
    public List<Goods> getData(int typeId, int startIndex, int pageSize) {
        QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select * from tb_goods where typeId = ? limit ?, ?";

        try {
            List<Goods> goodsList = qr.query(sql, new BeanListHandler<>(Goods.class), typeId, startIndex, pageSize);
            return goodsList;
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("查询商品分页数据失败");
        }
        return null;
    }
}

 

② 商品详情展示

页面

image-20220914114028058

serlvet

    /**
     * 根据商品id 查询商品详情
     * @param req
     * @param resp
     * @return
     * @throws Exception
     */
    public String getGoodsById(HttpServletRequest req, HttpServletResponse resp) throws Exception{
        int id = Integer.parseInt(req.getParameter("id"));

        //调用service ,根据id查询商品
        Goods goods = service.findById(id);

        req.setAttribute("goods", goods);

        return "forward:/goodsDetail.jsp";
    }

service接口

 Goods findById(int id);

service实现类

@Override
public Goods findById(int id) {
    //查询的商品详情信息
    Goods goods = dao.findById(id);
    //获取商品分类id
    int typeid = goods.getTypeid();
    GoodsTypeDao typeDao = new GoodsTypeDaoImpl();
    //查询商品分类信息
    GoodsType goodsType = typeDao.findById(typeid);
    goods.setGoodsType(goodsType);
    return goods;
}

GoodsDao接口

Goods findById(int id);

GoodsTypeDao接口

public GoodsType findById(int typeid);

GoodsTypeDao实现类

    public GoodsType findById(int typeid) {
        QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select * from tb_goods_type where  id = ?";
        try {
            GoodsType type = qr.query(sql, new BeanHandler<>(GoodsType.class), typeid);
            return type;
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("查询商品分类失败");
        }


        return null;
    }

GoodsDao实现类

@Override
public Goods findById(int id) {
    QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
    String sql = "select * from tb_goods where id = ?";
    try {
        Goods goods = qr.query(sql, new BeanHandler<>(Goods.class), id);
        return goods;
    } catch (SQLException e) {
        e.printStackTrace();
        System.out.println("获取商品详情失败");
    }
    return null;
}

 

4、购物车功能

① 添加到购物车

页面

<div class="col-xs-6 col-md-6">
  <div class="panel panel-default" style="height: 560px">
    <div class="panel-heading">商品详情</div>
      <div class="panel-body">
        <h3>产品名称:<small>${goods.name}</small></h3>
          <div style="margin-left: 10px;">

          <p>市场价格:&nbsp;&nbsp;&nbsp;<span class="text-danger" style="font-size: 15px;">${goods.price}</span>&nbsp;&nbsp;&nbsp;<span class="glyphicon glyphicon-yen"></span></p> 
            <p>上市时间:&nbsp;&nbsp;&nbsp;${goods.pubdate}</p>
              <p>热销指数:&nbsp;&nbsp;&nbsp;
<c:forEach begin="1" end="${goods.star}">
  <img src="image/star_red.gif" alt="star"/>
  </c:forEach>
    </p>
    <p>详细介绍:</p>
      <p>&nbsp;&nbsp;${goods.intro }</p>
        <a href="${pageContext.request.contextPath}/cartservlet?method=addCart&goodsId=${goods.id}&number=1" class="btn btn-warning">加入购物车&nbsp;&nbsp;&nbsp;<span class="glyphicon glyphicon-shopping-cart"></span></a>&nbsp;&nbsp;&nbsp;
<button class="btn btn-danger">直接购买</button>
  </div>
  </div>
  </div>
  </div>

serlvet

package com.qf.xiaomi.web.servlet;

import com.qf.xiaomi.pojo.Cart;
import com.qf.xiaomi.pojo.Goods;
import com.qf.xiaomi.pojo.User;
import com.qf.xiaomi.service.CartService;
import com.qf.xiaomi.service.GoodsService;
import com.qf.xiaomi.service.impl.CartServiceImpl;
import com.qf.xiaomi.service.impl.GoodsServiceImpl;
import com.qf.xiaomi.web.base.BaseServlet;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author 千锋教育
 * @Company http://www.mobiletrain.org/
 * @Version 1.0
 */
@WebServlet("/cartservlet")
public class CartServlet extends BaseServlet {

    CartService service = new CartServiceImpl();
    /**
     * 添加到 购物车
     *
     *  先判断该用户是否在购物车中 添加了某商品
     *      如果添加了, 则修改
     *      如果没有添加,则新增
     * @param req
     * @param resp
     * @return
     * @throws Exception
     */
    public String addCart(HttpServletRequest req, HttpServletResponse resp ) throws  Exception {
        //获取请求参数
        int goodsId = Integer.parseInt(req.getParameter("goodsId"));
        int number = Integer.parseInt(req.getParameter("number"));
        //从session中获取 用户信息
        User user = (User) req.getSession().getAttribute("user");

        //查询某用户在购物车是否存在某商品
        //根据用户id和商品id查询 购物车对象
        Cart cart = service.findCartByUIdAndGoodsId(user.getId(), goodsId);
        //根据商品id,查询商品信息
        GoodsService goodsService = new GoodsServiceImpl();
        Goods goods = goodsService.findById(goodsId);
        //获取商品的架构
        double price = goods.getPrice();

        //如果cart = null, 则说明该用户的购物车不存在此商品, 添加到购物车
        if(cart == null){
            //创建购物车对象
            cart = new Cart();
            //用户id
            cart.setId(user.getId());
            cart.setPid(goodsId);
            cart.setNum(number);
            cart.setMoney(number * price);

            service.insert(cart);
        }
        //否则说明该用户的购物车存在此商品,修改购物车的数量和总价
        else {
            cart.setNum(cart.getNum() + number);
            cart.setMoney(cart.getNum() * price);

            service.update(cart);
        }


        return "redirect:/cartSuccess.jsp";
    }
}

service接口

public interface CartService {
    Cart findCartByUIdAndGoodsId(int id, int goodsId);

    void insert(Cart cart);

    void update(Cart cart);
}

service实现类

package com.qf.xiaomi.web.servlet;

import com.qf.xiaomi.pojo.Cart;
import com.qf.xiaomi.pojo.Goods;
import com.qf.xiaomi.pojo.User;
import com.qf.xiaomi.service.CartService;
import com.qf.xiaomi.service.GoodsService;
import com.qf.xiaomi.service.impl.CartServiceImpl;
import com.qf.xiaomi.service.impl.GoodsServiceImpl;
import com.qf.xiaomi.web.base.BaseServlet;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author 千锋教育
 * @Company http://www.mobiletrain.org/
 * @Version 1.0
 */
@WebServlet("/cartservlet")
public class CartServlet extends BaseServlet {

    CartService service = new CartServiceImpl();
    /**
     * 添加到 购物车
     *
     *  先判断该用户是否在购物车中 添加了某商品
     *      如果添加了, 则修改
     *      如果没有添加,则新增
     * @param req
     * @param resp
     * @return
     * @throws Exception
     */
    public String addCart(HttpServletRequest req, HttpServletResponse resp ) throws  Exception {
        //获取请求参数
        int goodsId = Integer.parseInt(req.getParameter("goodsId"));
        int number = Integer.parseInt(req.getParameter("number"));
        //从session中获取 用户信息
        User user = (User) req.getSession().getAttribute("user");

        //查询某用户在购物车是否存在某商品
        //根据用户id和商品id查询 购物车对象
        Cart cart = service.findCartByUIdAndGoodsId(user.getId(), goodsId);
        //根据商品id,查询商品信息
        GoodsService goodsService = new GoodsServiceImpl();
        Goods goods = goodsService.findById(goodsId);
        //获取商品的架构
        double price = goods.getPrice();

        //如果cart = null, 则说明该用户的购物车不存在此商品, 添加到购物车
        if(cart == null){
            //创建购物车对象
            cart = new Cart();
            //用户id
            cart.setId(user.getId());
            cart.setPid(goodsId);
            cart.setNum(number);
            cart.setMoney(number * price);

            service.insert(cart);
        }
        //否则说明该用户的购物车存在此商品,修改购物车的数量和总价
        else {
            cart.setNum(cart.getNum() + number);
            cart.setMoney(cart.getNum() * price);

            service.update(cart);
        }


        return "redirect:/cartSuccess.jsp";
    }
}

dao接口

public interface CartDao {
    Cart findCartByUIdAndGoodsId(int uid, int goodsId);

    void insert(Cart cart);

    void update(Cart cart);
}

dao实现类

package com.qf.xiaomi.dao.impl;

import com.qf.xiaomi.dao.CartDao;
import com.qf.xiaomi.pojo.Cart;
import com.qf.xiaomi.utils.DataSourceUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

import java.sql.SQLException;

/**
 * @author 千锋教育
 * @Company http://www.mobiletrain.org/
 * @Version 1.0
 */
public class CartDaoImpl implements CartDao {
    @Override
    public Cart findCartByUIdAndGoodsId(int uid, int goodsId) {
        QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select * from tb_cart where id = ? and pid = ?";
        try {
            Cart cart = qr.query(sql, new BeanHandler<>(Cart.class), uid, goodsId);
            return  cart;
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("查询购物车失败");
        }

        return null;
    }

    @Override
    public void insert(Cart cart) {
        QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "INSERT INTO `tb_cart` (`id`, `pid`, `Num`, `money`) VALUES (?, ?, ?, ?)";
        try {
            qr.update(sql, cart.getId(), cart.getPid(),cart.getNum(), cart.getMoney());
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("新增购物车失败");
        }
    }

    @Override
    public void update(Cart cart) {
        QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "UPDATE `tb_cart` SET  `Num`=?, `money`=? WHERE (`id`=?) AND (`pid`=?);";
        try {
            qr.update(sql,cart.getNum(), cart.getMoney(), cart.getId(), cart.getPid());
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("修改购物车失败");
        }
    }
}

 

② 修改商品数量

页面

function pNum(pid,p,no){
		$.ajax({
			url:"cartservlet?method=addCartAjax&goodsId="+pid+"&number=1",
			method:"get",
			success:function(){
				location.href = "cartservlet?method=getCart";
			},
			error:function(){
				alert("服务器异常");
			}
		})
	}

serlvet

public void addCartAjax(HttpServletRequest req, HttpServletResponse resp ) throws  Exception {
        //获取当前登录的用户
        User user = (User) req.getSession().getAttribute("user");
        //获取 前端参数
        int goodsId = Integer.parseInt(req.getParameter("goodsId"));
        int number = Integer.parseInt(req.getParameter("number"));
        //如果number = 0,删除 该商品对应的购物车
        if(number == 0) {
            service.deleteCart(goodsId, user.getId());
        }else {
            //查询商品对象
            GoodsService goodsService = new GoodsServiceImpl();
            Goods goods = goodsService.findById(goodsId);

            //根据用户id和商品id查询购物车对象
            Cart cart = service.findCartByUIdAndGoodsId(user.getId(), goodsId);
            //如果cart = null, 说明该用户没有添加此商品到购物车,则新增到购物车
            if(cart == null) {
                cart = new Cart();
                cart.setId(user.getId());
                cart.setPid(goodsId);
                cart.setNum(1);
                cart.setMoney(goods.getPrice());

                service.insert(cart);
            }
            //如果cart != null, 说明该用户已经添加此商品到购物车,则更新购物车
            else {
                cart.setNum(cart.getNum() + number);
                cart.setMoney(cart.getNum() * goods.getPrice());

                service.update(cart);
            }
        }



    }

service接口

void deleteCart(int goodsId, int uid);

service实现类

@Override
    public void deleteCart(int goodsId, int uid) {
        dao.deleteCart(uid, goodsId);
    }

dao接口

void deleteCart(int uid, int goodsId);

dao实现类

@Override
    public void deleteCart(int uid, int goodsId) {
        QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "delete from tb_cart where id = ? and pid = ?";
        try {
            qr.update(sql , uid, goodsId);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

 

③ 清空购物车

页面

function clearCart(){
		if(confirm("确定要清空吗")){
			$.ajax({
				url:"cartservlet?method=clearCartAjax",
				method:"get",
				success:function(){
					location.href = "cartservlet?method=getCart";
				},
				error:function(){
					alert("服务器异常");
				}
			})
		}
	}

serlvet

/**
     * 清空购物车
     * @param req
     * @param resp
     * @throws Exception
     */
    public void clearCartAjax(HttpServletRequest req, HttpServletResponse resp ) throws  Exception {
        //获取当前登录的用户
        User user = (User) req.getSession().getAttribute("user");
        service.clearCart(user.getId());

    }

service接口

void clearCart(int id);

service实现类

@Override
    public void clearCart(int uid) {
        dao.clearCart(uid);
    }

dao接口

void clearCart(int uid);

dao实现类

    @Override
    public void clearCart(int uid) {
        QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "delete from tb_cart where id = ?";
        try {
            qr.update(sql , uid);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

 

5、结账预览

页面

<div class="pull-right" style="margin-right: 40px;">
			
	            <div>
	            	<a id="removeAllProduct" href="javascript:clearCart()" class="btn btn-default btn-lg">清空购物车</a>
	            	&nbsp;&nbsp;
	            	<a href="${pageContext.request.contextPath}/orderservlet?method=getOrderView" class="btn  btn-danger btn-lg">结账</a>
	            	
	            </div>
	            <br><br>
	            <div style="margin-bottom: 20px;">        		  
	            	商品金额总计:<span id="total" class="text-danger"><b>¥&nbsp;&nbsp;${sum}</b></span>
	            </div>
		</div>

serlvet

public String getOrderView(HttpServletRequest req, HttpServletResponse resp ) throws  Exception {
        //获取该用户的 购物车信息
        User user = (User) req.getSession().getAttribute("user");
        List<Cart> carts = service.getCarts(user.getId());

        //获取 地址列表
        List<Address> addList = addressService.getAddrList(user.getId());


        //把数据存储到 请求域
        req.setAttribute("carts", carts);
        req.setAttribute("addList", addList);
        //请求转发到 前端
        return "forward:/order.jsp";
    }

service接口

public interface AddressService {
    List<Address> getAddrList(int id);
}

service实现类

public class AddressServiceImpl implements AddressService {

    AddressDao dao = new AddressDaoImpl();

    @Override
    public List<Address> getAddrList(int uid) {
        return dao.getAddList(uid);
    }
}

dao接口

public interface AddressDao {
    List<Address> getAddList(int uid);
}

dao实现类

public class AddressDaoImpl implements AddressDao {
    @Override
    public List<Address> getAddList(int uid) {
        QueryRunner qr  = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select * from tb_address where uid = ?";
        List<Address> addrList = null;
        try {
            addrList = qr.query(sql, new BeanListHandler<>(Address.class), uid);
            return addrList;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
}

 

6、地址管理功能

①查询收货地址

header页面

<a href="userAddress?flag=show" id="a_top">${user.username}</a>
<li>|</li>
<a href="userservlet?method=logOut" id="a_top">注销</a>
<li>|</li>
<a href="getOrderList" id="a_top">我的订单</a>
<li>|</li>
<a href="userservlet?method=getAddress" id="a_top">地址管理</a>

serlvet

public String getAddress(HttpServletRequest req, HttpServletResponse resp) throws Exception{
        //获取该用户的 购物车信息
        User user = (User) req.getSession().getAttribute("user");

        //获取 地址列表
        List<Address> addList = addressService.getAddrList(user.getId());
        //把数据存储到 请求域
        req.setAttribute("addList", addList);
        //请求转发到 前端
        return "forward:/self_info.jsp";
    }

service接口

public interface AddressService {
    List<Address> getAddrList(int id);
}

service实现类

public class AddressServiceImpl implements AddressService {

    AddressDao dao = new AddressDaoImpl();

    @Override
    public List<Address> getAddrList(int uid) {
        return dao.getAddList(uid);
    }
}

dao接口

public interface AddressDao {
    List<Address> getAddList(int uid);
}

dao实现类

public class AddressDaoImpl implements AddressDao {
    @Override
    public List<Address> getAddList(int uid) {
        QueryRunner qr  = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select * from tb_address where uid = ?";
        List<Address> addrList = null;
        try {
            addrList = qr.query(sql, new BeanListHandler<>(Address.class), uid);
            return addrList;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
}

 

② 添加地址

页面

<form action="userservlet?method=addAddress" method="post" class="form-horizontal">
  <div class="form-group">
    <label class="col-sm-2 form-label">收件人</label>
    <div class="col-sm-3">
      <input type="text" class="form-control" name="name"/>
    </div>
  </div>
  <div class="form-group">
    <label class="col-sm-2 form-label">手机号</label>
    <div class="col-sm-3">
      <input type="text" class="form-control" name="phone"/>
    </div>
  </div>	
  <div class="form-group">
    <label class="form-label">详细地址</label>
    <textarea rows="3" class="form-control" name="detail" ></textarea>	
  </div>
  <div class="form-group col-md-12">
    <input type="submit" class="btn btn-primary" value="添加地址">
  </div>
  <input type="hidden" value="${loginUser.id}" name="uid">
</form>

serlvet

 public String addAddress(HttpServletRequest req, HttpServletResponse resp) throws Exception{
        String name = req.getParameter("name");
        String phone = req.getParameter("phone");
        String detail = req.getParameter("detail");
        //获取该用户的 购物车信息
        User user = (User) req.getSession().getAttribute("user");
        int uid = user.getId();

        Address address = new Address();
        address.setUid(uid);
        address.setName(name);
        address.setDetail(detail);
        address.setPhone(phone);
        address.setLevel(0);
        addressService.addAddress(address);

        //新增之后,重新查询地址列表页面
        return "redirect:/userservlet?method=getAddress";
    }

service接口

void addAddress(Address address);

service实现类

@Override
    public void addAddress(Address address) {
        dao.addAddress(address);
    }

dao接口

void addAddress(Address address);

dao实现类

    @Override
    public void addAddress(Address address) {
        QueryRunner qr  = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "INSERT INTO `tb_address` ( `detail`, `name`, `phone`, `uid`, `level`) VALUES ( ?, ?, ?, ?, ?)";
        try {
            qr.update(sql , address.getDetail(), address.getName(), address.getPhone(),address.getUid(),address.getLevel());
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

 

③修改地址

页面

<td>
  <button onclick="deleteAddr(${address.id})" class="btn btn-danger btn-sm">删除</button>&nbsp;&nbsp;
  <button class="btn btn-default btn-sm" data-toggle="modal" data-target="#myModal${address.id}">修改</button>&nbsp;&nbsp;
  <!-- 弹出模态框 -->

  <div class="modal fade" tabindex="-1" role="dialog" id="myModal${address.id}">
    <div class="modal-dialog" role="document">
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal">
            <span>&times;</span>
          </button>
          <h4 class="modal-title">修改地址</h4>
        </div>
        <form action="userservlet?method=updateAddress" method="post" class="form-horizontal">
          <div class="motal-body">
            <div class="form-group">
              <label class="col-sm-2 control-label">收件人</label>
              <div class="col-sm-10">
                <input type="hidden" name="id" value="${address.id}">
                <input type="hidden" name="level" value="${address.level}">
                <input type="text" name="name" class="form-control" value="${address.name}">
              </div>
            </div>
            <div class="form-group">
              <label class="col-sm-2 control-label">电话</label>
              <div class="col-sm-10">
                <input type="text" name="phone" class="form-control" value="${address.phone}">
              </div>
            </div>
            <div class="form-group">
              <label class="col-sm-2 control-label">收件人</label>
              <div class="col-sm-10">
                <input type="text" name="detail" class="form-control" value="${address.detail}">
              </div>
            </div>

          </div>
          <div class="motal-footer">
            <button type="submit" class="btn btn-primary">修改</button>
          </div>
        </form>
      </div>
    </div>
  </div>

  <button onclick="defaultAddr(${address.id})" class="btn btn-primary btn-sm">设为默认</button>
  <c:if test="${address.level==1}">
    <span class="badge" style="">默认</span>
  </c:if>
  <c:if test="${address.level==0}">
    <span class="badge">普通</span>
  </c:if>
</td>

serlvet

public String updateAddress(HttpServletRequest req, HttpServletResponse resp) throws Exception{
        //获取参数数据
        int id = Integer.parseInt(req.getParameter("id"));
        String name = req.getParameter("name");
        String phone = req.getParameter("phone");
        String detail = req.getParameter("detail");
        //封装数据
        Address address = new Address();
        address.setId(id);
        address.setName(name);
        address.setDetail(detail);
        address.setPhone(phone);
        //更新数据
        addressService.updateAddress(address);

        //更新之后,重新查询地址列表页面
        return "redirect:/userservlet?method=getAddress";
    }

service接口

void updateAddress(Address address);

service实现类

@Override
    public void updateAddress(Address address) {
        dao.update(address);
    }

dao接口

 void update(Address address);

dao实现类

@Override
public void update(Address address) {
  QueryRunner qr  = new QueryRunner(DataSourceUtils.getDataSource());
  String sql = "UPDATE `tb_address` SET  `detail` = ?, `name`=?, `phone`=? WHERE (`id`=?)";
  try {
    qr.update(sql , address.getDetail(), address.getName(), address.getPhone(),address.getId());
  } catch (SQLException e) {
    e.printStackTrace();
  }
}

 

④设置默认地址

页面

<button onclick="defaultAddr(${address.id})" class="btn btn-primary btn-sm">设为默认</button>
<c:if test="${address.level==1}">
  <span class="badge" style="">默认</span>
</c:if>
<c:if test="${address.level==0}">
  <span class="badge">普通</span>
</c:if>

serlvet

public String defaultAddress(HttpServletRequest req, HttpServletResponse resp) throws Exception {
        //获取 地址ID
        String aId = req.getParameter("id");

        User user = (User) req.getSession().getAttribute("user");

        addressService.setDefaultAddress(user.getId(), aId);


        //修改之后,重新查询地址列表页面
        return "redirect:/userservlet?method=getAddress";
    }

service接口

  void setDefaultAddress(int id, String aId);

service实现类

 /**
     * 设置默认收货地址
     *
     *  1. 设置该用户的 所有收货地址都是 普通的
     *  2. 设置该用户的 某收货地址为默认收货地址
     * @param uid
     * @param aId
     */
    @Override
    public void setDefaultAddress(int uid, String aId) {
        Connection conn = DataSourceUtils.getConnection();
        try {
            //设置为不能自动提交
            conn.setAutoCommit(false);
            //把所有的收货地址都设置为 普通的
            dao.set2Normal(uid);
            //设置某收货地址为 默认收货地址
            dao.setDefaultAddress(aId);
            //提交事务
            conn.commit();
        }catch (Exception e ){
            e.printStackTrace();
            //回滚事务
            try {
                conn.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        }

    }

dao接口

  void set2Normal(int uid);

    void setDefaultAddress(String aId);

dao实现类

@Override
    public void set2Normal(int uid) {
        QueryRunner qr  = new QueryRunner();
        String sql = "UPDATE `tb_address` SET  level = 0 WHERE (`uid`=?)";
        try {
            qr.update(DataSourceUtils.getConnection(), sql , uid);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void setDefaultAddress(String aId) {
        QueryRunner qr  = new QueryRunner();
        String sql = "UPDATE `tb_address` SET  level = 1 WHERE (`id`=?)";
        try {
            qr.update(DataSourceUtils.getConnection(), sql , aId);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

 

7、提交订单功能

IOrder.jsp页面

<div class="row pull-right" style="margin-right: 40px;">
		 <div style="margin-bottom: 20px;">
	            <button  id="btn_add" class="btn  btn-danger btn-lg" type="button">提交订单</button>
	     </div>
	</div>

serlvet

/**
     * 提交订单
     * @param req
     * @param resp
     * @return
     * @throws Exception
     */
    public String addOrder(HttpServletRequest req, HttpServletResponse resp ) throws  Exception {
        //获取 收货地址id
        Integer aid = Integer.parseInt(req.getParameter("aid"));
        User user = (User) req.getSession().getAttribute("user");

        Order order = orderService.addOrder(aid, user.getId());
        //把订单对象存储到请求域
        req.setAttribute("order", order);


        return "forward:/orderSuccess.jsp";
    }

service接口

public interface OrderService {
    Order addOrder(Integer aid, int uid);
}

service实现类

   /**
     * 提交订单
     *  1. 获取当前用户购物车数据
     *  2. 添加 order 订单表
     *  3. 添加 orderDetails 订单详情表
     *  4. 清空购物车
     * @param aid
     * @param uid
     */
    @Override
    public Order addOrder(Integer aid, int uid) {
        //当前用户购物车数据
        List<Cart> carts = cartDao.getCart(uid);
        double sum = 0;
        //计算订单的总额
        for (Cart cart : carts) {
            sum += cart.getMoney();
        }

        //添加订单
        Order order = new Order();
        //手动生成订单编号(唯一)
        String orderId = RandomUtils.createActive();

        order.setId(orderId);
        order.setStatus("1");
        order.setUid(uid);
        order.setAid(aid);
        order.setMoney(sum);
        order.setTime(new Date());

        orderDao.insert(order);

        //添加订单详情(一个购物车对象,对应一个订单详情)
        for (Cart cart : carts) {
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setOid(orderId); //订单id
            orderDetail.setPid(cart.getPid()); //商品id
            orderDetail.setNum(cart.getNum()); //数量
            orderDetail.setMoney(cart.getMoney()); //价格


            orderDetailDao.insert(orderDetail);
        }


        //清空购物车
        cartDao.clearCart(uid);

        return order;
    }

dao接口

public interface OrderDao {
    void insert(Order order);
}
public interface OrderDetailDao  {
    void insert(OrderDetail orderDetail);
}

dao实现类

public class OrderDaoImpl implements OrderDao {
    @Override
    public void insert(Order order) {
        QueryRunner qr = new QueryRunner();

        String sql = "INSERT INTO `tb_order` (`id`, `uid`, `money`, `status`, `time`, `aid`) VALUES (?,?,?,?,?,?)";

        try {
            qr.update(DataSourceUtils.getConnection(), sql, order.getId(), order.getUid(),order.getMoney(), order.getStatus(),order.getTime(), order.getAid());
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }

}

public class OrderDetailDaoImpl implements OrderDetailDao {
    @Override
    public void insert(OrderDetail orderDetail) {
        QueryRunner qr = new QueryRunner();

        String sql = "INSERT INTO `tb_orderdetail` (`id`, `Oid`, `pid`, `num`, `Money`) VALUES (null, ?,?,?,?)";

        try {
            qr.update(DataSourceUtils.getConnection(), sql, orderDetail.getOid(),orderDetail.getPid(), orderDetail.getNum(),orderDetail.getMoney());
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

 

8、支付功能

支付地址: http://weixin.chenjunbo.xin/payment/weixinpay

页面

<form  action="http://weixin.chenjunbo.xin/payment/weixinpay" method="get">
  <table class="table table-bordered table-striped table-hover">
    <tr>
      <td colspan="1">订单号:</td>
      <td colspan="3"><input type="text" class="form-control" name="orderId" value="<%=request.getParameter("oid")%>" readonly="readonly"></td>
    </tr>
    <tr>
      <td colspan="1">支付金额:</td>
      <td colspan="3">
        <div class="input-group" style="width: 200px;">
          <input type="text" class="form-control"  name="price" value="1">
          <div class="input-group-addon"><span class="glyphicon glyphicon-yen"></span></div>
        </div>
      </td>
    </tr>
    <tr>
      <td colspan="1">商品介绍:</td>
      <td colspan="3"><input type="text" class="form-control" name="body" value="xiaomi2" readonly="readonly">
        <!-- 设置 程序回传到的链接地址 -->
        <input type="hidden" class="form-control" name="url" value="http://localhost:8080/orderservlet?method=paySuccess">
      </td>
    </tr>

  </table>
  <div class="pull-right" style="margin-right: 30px;">
    <input type="submit" value="确认支付" class="btn btn-warning btn-lg">

  </div>
</form>

serlvet

//支付成功的 方法
    public String paySuccess(HttpServletRequest req, HttpServletResponse resp ) throws  Exception {
        String result = req.getParameter("result");
//        System.out.println(result);
        JSONObject jsonObject = JSON.parseObject(result);
        Object result1 = jsonObject.get("result");
        JSONObject jsonObject1 = JSON.parseObject(result1.toString());
        String return_code = jsonObject1.getString("return_code");
        String orderId = jsonObject1.getString("out_trade_no");
        //如果支付成功了, 更新订单的状态
        if("SUCCESS".equalsIgnoreCase(return_code)) {
            orderService.updateOrderStatus(orderId, "2");
        }

        return "redirect:/orderservlet?method=getOrderList";
    }

service接口

void updateOrderStatus(String orderId, String s);

service实现类

@Override
    public void updateOrderStatus(String orderId, String status) {
        orderDao.updateStatus(orderId, status);
    }

dao接口

void updateStatus(String orderId, String status);

dao实现类

@Override
    public void updateStatus(String orderId, String status) {
        QueryRunner qr = new QueryRunner();

        String sql = "update tb_order set status = ? where id = ?";

        try {
            qr.update(DataSourceUtils.getConnection(), sql, status, orderId );
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

 

9、获取订单列表

支付地址: http://weixin.chenjunbo.xin/payment/weixinpay

 

serlvet

public String getOrderList(HttpServletRequest req, HttpServletResponse resp ) throws  Exception {
        User user = (User) req.getSession().getAttribute("user");
        List<Order> orders = orderService.getOrderList(user.getId());
        req.setAttribute("orderList", orders);
        return "forward:/orderList.jsp";
    }

service接口

List<Order> getOrderList(int id);

service实现类

@Override
    public List<Order> getOrderList(int uid) {
        return orderDao.getOrderList(uid);
    }

dao接口

List<Order> getOrderList(int uid);

dao实现类

@Override
    public List<Order> getOrderList(int uid) {
        QueryRunner qr = new QueryRunner();

        String sql = "select * from tb_order where uid = ?";

        try {
            List<Order> orderList = qr.query(DataSourceUtils.getConnection(), sql, new BeanListHandler<>(Order.class), uid);
            return orderList;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
 
posted @   ITboy搬砖人  阅读(391)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· 单线程的Redis速度为什么快?
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
点击右上角即可分享
微信分享提示