第14章 网上蛋糕商城-前端开发


学习目标

1 用户注册功能

图1 用户注册功能
图2 分层实现

1.1 前台首页

web/header.jsp 页眉

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!--header-->
<div class="header">
    <div class="container">
        <nav class="navbar navbar-default" role="navigation">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <h1 class="navbar-brand"><a href="index"></a></h1>
            </div>
            <!--navbar-header-->
            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                <ul class="nav navbar-nav">
                    <li><a href="index" <c:if test="${param.flag==1}">class="active"</c:if>>首页</a></li>
                    <li class="dropdown">
                        <a href="#" class="dropdown-toggle <c:if test="${param.flag==2}">active</c:if>" data-toggle="dropdown">商品分类<b class="caret"></b></a>
                        <ul class="dropdown-menu multi-column columns-2">
                            <li>
                                <div class="row">
                                    <div class="col-sm-12">
                                        <h4>商品分类</h4>
                                        <ul class="multi-column-dropdown">
                                            <li><a class="list" href="goods_list">全部系列</a></li>
                                            <c:forEach items="${typeList}" var="t">
                                                <li><a class="list" href="goods_list?typeid=${t.id}">${t.名称}</a></li>
                                            </c:forEach>
                                        </ul>
                                    </div>
                                </div>
                            </li>
                        </ul>
                    </li>
                    <li><a href="goodsrecommend_list?type=2" <c:if test="${param.flag==3 && t==2}">class="active"</c:if>>热销</a></li>
                    <li><a href="goodsrecommend_list?type=3" <c:if test="${param.flag==3 && t==3}">class="active"</c:if>>新品</a></li>

                    <c:choose><c:when test="${empty user }">
                        <li><a href="user_register.jsp" <c:if test="${param.flag==10 }">class="active"</c:if>>注册</a></li>
                        <li><a href="user_login.jsp" <c:if test="${param.flag==9 }">class="active"</c:if>>登录</a></li>
                    </c:when><c:otherwise>
                        <li><a href="order_list" <c:if test="${param.flag==5 }">class="active"</c:if>>我的订单</a></li>
                        <li><a href="user_center.jsp" <c:if test="${param.flag==4 }">class="active"</c:if>>个人中心</a></li>
                        <li><a href="user_logout" >退出</a></li>
                    </c:otherwise>
                    </c:choose>

                    <c:if test="${!empty user && user.是否管理员 }">
                        <li><a href="admin/index.jsp" target="_blank">后台管理</a></li>
                    </c:if>
                </ul>
                <!--/.navbar-collapse-->
            </div>
            <!--//navbar-header-->
        </nav>
        <div class="header-info">
            <div class="header-right search-box">
                <a href="javascript:;"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></a>
                <div class="search">
                    <form class="navbar-form" action="goods_search">
                        <input type="text" class="form-control" name="keyword">
                        <button type="submit" class="btn btn-default <c:if test="${param.flag==7 }">active</c:if>" aria-label="Left Align">搜索</button>
                    </form>
                </div>
            </div>

            <div class="header-right cart">
                <a href="goods_cart.jsp">
                    <span class="glyphicon glyphicon-shopping-cart <c:if test="${param.flag==8 }">active</c:if>" aria-hidden="true"><span class="card_num"><c:choose><c:when test="${empty order}">0</c:when><c:otherwise>${order.商品总数}</c:otherwise></c:choose></span></span>
                </a>
            </div>
            <div class="clearfix"> </div>
        </div>
        <div class="clearfix"> </div>
    </div>
</div>
<!--//header-->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!--footer-->
<div class="footer">
    <div class="container">
        <div class="text-center">
            <p>巩浩伟 http://101.42.18.121/ ©版权所有。</p>
        </div>
    </div>
</div>
<!--//footer-->

web/index.jsp 首页

复制 web/js,css,fonts,layer,picture 目录及其文件

<%@ page contentType="text/html;charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<!DOCTYPE html>
<html>
<head>
    <title>巩浩伟在线网上蛋糕商城</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/bootstrap.css">
    <link rel="stylesheet" href="css/style.css">
    <script src="js/jquery.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script src="layer/layer.js"></script>
    <script src="js/cart.js"></script>
</head>
<body>
<!--header-->
<jsp:include page="/header.jsp">
    <jsp:param name="flag" value="1"></jsp:param>
</jsp:include>
<!--banner-->

<div class="banner">
    <div class="container">
        <div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
            <!-- Indicators -->
            <ol class="carousel-indicators" id="olnum">
                <c:forEach items="${scroll}" var="g" varStatus="status">
                    <c:choose>
                        <c:when test="${status.first}">
                            <li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
                        </c:when>
                        <c:otherwise>
                            <li data-target="#carousel-example-generic" data-slide-to="${status.index}"></li>
                        </c:otherwise>
                    </c:choose>
                </c:forEach>
            </ol>

            <!-- Wrapper for slides -->
            <div class="carousel-inner" role="listbox" id="lunbotu" style="width: 1242px; height: 432px;">
                <c:forEach items="${scroll}" var="g" varStatus="status">
                    <c:choose>
                        <c:when test="${status.first}">
                            <div class="item active">
                                <h2 class="hdng"><a href="goods_detail?id=${g.id}">${g.商品名称}</a><span></span></h2>
                                <p>今日精选推荐</p>
                                <a class="banner_a" href="javascript:;" onclick="buy(${g.id})">加入购物车</a>
                                <div class="banner-text">
                                    <a href="goods_detail?id=${g.id}">
                                        <img src="${g.商品主图}" alt="${g.商品名称}" width="350" height="350">
                                    </a>
                                </div>
                            </div>
                        </c:when>
                        <c:otherwise>
                            <div class="item">
                                <h2 class="hdng"><a href="goods_detail?id=${g.id}">${g.商品名称}</a><span></span></h2>
                                <p>今日精选推荐</p>
                                <a class="banner_a" href="javascript:;" onclick="buy(${g.id})">加入购物车</a>
                                <div class="banner-text">
                                    <a href="goods_detail?id=${g.id}">
                                        <img src="${g.商品主图}" alt="${g.商品名称}" width="350" height="350">
                                    </a>
                                </div>
                            </div>
                        </c:otherwise>
                    </c:choose>
                </c:forEach>
            </div>

            <!-- Controls -->
            <%--<a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
                <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
                <span class="sr-only">Previous</span>
            </a>
            <a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
                <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
                <span class="sr-only">Next</span>
            </a>--%>
        </div>
    </div>
</div>

<!--//banner-->

<div class="subscribe2"></div>

<!--gallery-->
<div class="gallery">
    <div class="container">
        <div class="alert alert-danger">热销推荐</div>
        <div class="gallery-grids">
            <c:forEach items="${hotList}" var="g">
                <div class="col-md-4 gallery-grid glry-two">
                    <a href="goods_detail?id=${g.id}">
                        <img src="${g.商品主图}" class="img-responsive" alt="${g.商品名称}" width="350" height="350"/>
                    </a>
                    <div class="gallery-info galrr-info-two">
                        <p>
                            <span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span>
                            <a href="goods_detail?id=${g.id}">查看详情</a>
                        </p>
                        <a class="shop" href="javascript:;" onclick="buy(${g.id})">加入购物车</a>
                        <div class="clearfix"></div>
                    </div>
                    <div class="galy-info">
                        <p>${g.分类名称} > ${g.商品名称}</p>
                        <div class="galry">
                            <div class="prices">
                                <h5 class="item_price">¥ ${g.单价}</h5>
                            </div>
                            <div class="clearfix"></div>
                        </div>
                    </div>
                </div>
            </c:forEach>
        </div>

        <div class="clearfix"></div>
        <div class="alert alert-info">新品推荐</div>
        <div class="gallery-grids">
            <c:forEach items="${newList}" var="g">
                <div class="col-md-3 gallery-grid ">
                    <a href="goods_detail?id=${g.id}">
                        <img src="${g.商品主图}" class="img-responsive" alt="${g.商品名称}"/>
                    </a>
                    <div class="gallery-info">
                        <p>
                            <span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span>
                            <a href="goods_detail?id=${g.id}">查看详情</a>
                        </p>
                        <a class="shop" href="javascript:;" onclick="buy(${g.id})">加入购物车</a>
                        <div class="clearfix"></div>
                    </div>
                    <div class="galy-info">
                        <p>${g.分类名称} > ${g.商品名称}</p>
                        <div class="galry">
                            <div class="prices">
                                <h5 class="item_price">¥ ${g.单价}</h5>
                            </div>
                            <div class="clearfix"></div>
                        </div>
                    </div>
                </div>
            </c:forEach>
        </div>
    </div>
</div>
<!--//gallery-->

<!--subscribe-->
<div class="subscribe"></div>
<!--//subscribe-->

<!--footer-->
<jsp:include page="/footer.jsp"></jsp:include>
</body>
</html>
图3 首页界面(没有完善的)

1.2 创建model

cn.ghw.model.User.java 用户

package cn.ghw.model;
import lombok.Data;

@Data
public class User {
    private int id;
    private String 用户名;
    private String 邮箱;
    private String 密码;
    private String 名称;  //姓名或单位名称
    private String 电话;
    private String 地址;
    private boolean 是否管理员=false;
    private boolean 是否有效=false;

    public User(int id, String 用户名, String 邮箱, String 密码, String 名称, String 电话, String 地址,
                boolean 是否管理员, boolean 是否有效) {
        this.id = id;
        this.用户名 = 用户名;
        this.邮箱 = 邮箱;
        this.密码 = 密码;
        this.名称 = 名称;
        this.电话 = 电话;
        this.地址 = 地址;
        this.是否管理员 = 是否管理员;
        this.是否有效 = 是否有效;
    }

    public User( String 用户名, String 邮箱, String 密码, String 名称, String 电话, String 地址) {
        this.用户名 = 用户名;
        this.邮箱 = 邮箱;
        this.密码 = 密码;
        this.名称 = 名称;
        this.电话 = 电话;
        this.地址 = 地址;
        this.是否管理员 = false;
        this.是否有效 = false;
    }

    public User() {

    }

}

1.3 创建dao

cn.ghw.dao.UserDao.java

package cn.ghw.dao;

import cn.ghw.model.User;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import cn.ghw.utils.DataSourceUtils;
import java.sql.SQLException;

public class UserDao {
    public void adghwser(User user) throws SQLException {
        QueryRunner r = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "insert into 用户表_ghw(用户名,邮箱,密码,名称,电话,地址,是否管理员,是否有效) values(?,?,?,?,?,?,?,?)";
        r.update(sql,user.get用户名(),user.get邮箱(),user.get密码(),user.get名称(),user.get电话(),user.get地址(),user.is是否管理员(),user.is是否有效());
    }

    public boolean isUsernameExist(String username) throws SQLException {
        QueryRunner r = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select * from 用户表_ghw where 用户名 = ?";
        User u = r.query(sql, new BeanHandler<User>(User.class),username);
        if(u==null) {
            return false;
        }else {
            return true;
        }
    }

    public boolean isEmailExist(String email) throws SQLException {
        QueryRunner r = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select * from 用户表_ghw where 邮箱 = ?";
        User u = r.query(sql, new BeanHandler<User>(User.class),email);
        if(u==null) {
            return false;
        }else {
            return true;
        }
    }
}

1.4 编写Service层方法

cn.ghw.service.UserService.java

package cn.ghw.service;

import cn.ghw.dao.UserDao;
import cn.ghw.model.Page;
import cn.ghw.model.User;
import java.sql.SQLException;
import java.util.List;

public class UserService {
    private UserDao uDao = new UserDao();
    public boolean register(User user) {
        try {
            if(uDao.isUsernameExist(user.get用户名())) {
                return false;
            }
            if(uDao.isEmailExist(user.get邮箱())) {
                return false;
            }
            uDao.adghwser(user);
            return true;
        } catch (SQLException e) {
              e.printStackTrace();
        }
        return false;
    }
}

1.5 编写Servlet层方法

cn.ghw.servlet.UserRegisterServlet.java

package cn.ghw.servlet;

import cn.ghw.model.User;
import org.apache.commons.beanutils.BeanUtils;
import cn.ghw.service.UserService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

@WebServlet("/user_rigister")
public class UserRegisterServlet extends HttpServlet {
    private UserService uService = new UserService();
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        User user = new User();
        try {
            BeanUtils.copyProperties(user, request.getParameterMap());
            // System.out.println(user.toString());
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        if(uService.register(user)) {
            request.setAttribute("msg", "注册成功,请登录!");
            request.getRequestDispatcher("user_login.jsp").forward(request, response);
        }else {
            request.setAttribute("msg", "用户名或邮箱重复,请重新填写!");
            request.getRequestDispatcher("user_register.jsp").forward(request, response);
        }
    }
}

1.6 编写注册页面

web/user_register.jsp

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
    <title>用户注册</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/bootstrap.css">
    <link rel="stylesheet" href="css/style.css">
    <script src="js/jquery.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script src="js/simpleCart.min.js"></script>
</head>
<body>

    <!--header-->
    <jsp:include page="/header.jsp">
        <jsp:param name="flag" value="10"></jsp:param>
    </jsp:include>
    <!--//header-->

    <!--account-->
    <div class="account">
        <div class="container">
            <div class="register">
                <c:if test="${!empty msg }">
                    <div class="alert alert-danger">${msg }</div>
                </c:if>
                <form action="user_rigister" method="post">
                    <div class="register-top-grid">
                        <h3>注册新用户</h3>
                        <div class="input">
                            <span>用户名 <label style="color:red;">*</label></span>
                            <input type="text" name="用户名" placeholder="请输入用户名" required="required">
                        </div>
                        <div class="input">
                            <span>邮箱 <label style="color:red;">*</label></span>
                            <input type="text" name="邮箱" placeholder="请输入邮箱" required="required">
                        </div>
                        <div class="input">
                            <span>密码 <label style="color:red;">*</label></span>
                            <input type="password" name="密码" placeholder="请输入密码" required="required">
                        </div>
                        <div class="input">
                            <span>姓名或名称<label></label></span>
                            <input type="text" name="名称" placeholder="请输入姓名或名称">
                        </div>
                        <div class="input">
                            <span>电话<label></label></span>
                            <input type="text" name="电话" placeholder="请输入收货电话">
                        </div>
                        <div class="input">
                            <span>地址<label></label></span>
                            <input type="text" name="地址" placeholder="请输入收货地址">
                        </div>
                        <div class="clearfix"> </div>
                    </div>
                    <div class="register-but text-center">
                       <input type="submit" value="提交">
                       <div class="clearfix"> </div>
                    </div>
                </form>
                <div class="clearfix"> </div>
            </div>
        </div>
    </div>
    <!--//account-->

    <!--footer-->
    <jsp:include page="footer.jsp"></jsp:include>
    <!--//footer-->
</body>
</html>
图4 注册界面

VM标志启用/禁用增量注解处理环境

文件 -- 设置 -- 构建、执行、部署 -- 编译器 -- 共享构建过程 VM 选项:-Djps.track.ap.dependencies=false

图5 VM标志启用/禁用增量注解处理环境
图6 VM标志启用/禁用增量注解处理环境--清除缓存

2 用户登录功能

图7 登录流程
图8 用户登录功能的实现步骤

2.1 UserDao.java 添加登录有关dao层方法

cn.ghw.dao.UserDao.java

public class UserDao {
    ...
    public User selectByUsernamePassword(String username,String password) throws SQLException {
        QueryRunner r = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select * from 用户表_ghw where 用户名=? and 密码=?";
        return r.query(sql, new BeanHandler<User>(User.class),username,password);
    }
    public User selectByEmailPassword(String email,String password) throws SQLException {
        QueryRunner r = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select * from 用户表_ghw where 邮箱=? and 密码=?";
        return r.query(sql, new BeanHandler<User>(User.class),email,password);
    }
    ...
}

2.2 UserService.java编写有关登录的业务层方法

cn.ghw.service.UserService.java 增加有关登录的业务层方法

package cn.ghw.service;

public class UserService {
    private UserDao uDao = new UserDao();
    ...
    public User login(String ue,String password) {
        User user=null;
        try {
            user = uDao.selectByUsernamePassword(ue, password);
        } catch (SQLException e) {
             e.printStackTrace();
        }
        if(user!=null) {
            return user;
        }
        try {
            user=uDao.selectByEmailPassword(ue, password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        if(user!=null) {
            return user;
        }
        return null;
    }
    ...
}

2.3 编写有关登录Servlet层方法

cn.ghw.servlet.UserLoginServlet.java

package cn.ghw.servlet;

import cn.ghw.model.User;
import cn.ghw.service.UserService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/user_login")
public class UserLoginServlet extends HttpServlet {
    private UserService uService = new UserService();

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String ue = request.getParameter("ue");
        String password = request.getParameter("password");
        User user = uService.login(ue, password);
        if(user==null) {
            request.setAttribute("failMsg", "用户名、邮箱或者密码错误,请重新登录!");
            request.getRequestDispatcher("/user_login.jsp").forward(request, response);
        }else {
            request.getSession().setAttribute("user", user);
            request.getRequestDispatcher("/user_center.jsp").forward(request, response);
        }
    }
}

2.4 编写登录页面

web/user_login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<!DOCTYPE html>
<html>
<head>
    <title>用户登录</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/bootstrap.css">
    <link rel="stylesheet" href="css/style.css">
    <script src="js/jquery.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script src="js/simpleCart.min.js"></script>
</head>
<body>
    <!--header-->
    <jsp:include page="header.jsp">
        <jsp:param name="flag" value="9"></jsp:param>
    </jsp:include>
    <!--//header-->

    <!--account-->
    <div class="account">
        <div class="container">
            <div class="register">
                <c:if test="${!empty msg }">
                    <div class="alert alert-success">${msg }</div>
                </c:if>
                <c:if test="${!empty failMsg }">
                    <div class="alert alert-danger">${failMsg }</div>
                </c:if>

                <form action="user_login" method="post">
                    <div class="register-top-grid">
                        <h3>用户登录</h3>
                        <div class="input">
                            <span>用户名/邮箱 <label style="color:red;">*</label></span>
                            <input type="text" name="ue" placeholder="请输入用户名" required="required">
                        </div>
                        <div class="input">
                            <span>密码 <label style="color:red;">*</label></span>
                            <input type="password" name="password" placeholder="请输入密码" required="required">
                        </div>

                        <div class="clearfix"> </div>
                    </div>
                    <div class="register-but text-center">
                        <input type="submit" value="提交">
                        <div class="clearfix"> </div>
                    </div>
                </form>
                <div class="clearfix"> </div>
            </div>
        </div>
    </div>
    <!--//account-->

    <!--footer-->
    <jsp:include page="footer.jsp"></jsp:include>
    <!--//footer-->

</body>
</html>
图9 登录界面

用户名、密码正确后会出现临时性的404错误--个人中心。

3 个人中心

3.1 UserDao.java 添加有关修改个人信息、密码dao层方法

cn.ghw.dao.UserDao.java

public class UserDao {
    ...
    public void updateUserAddress(User user) throws SQLException {
        QueryRunner r = new QueryRunner(DataSourceUtils.getDataSource());
        String sql ="update 用户表_ghw set 名称 = ?,电话=?,地址=? where id = ?";
        r.update(sql,user.get名称(),user.get电话(),user.get地址(),user.getId());
    }

    public void updatePwd(User user) throws SQLException {
        QueryRunner r = new QueryRunner(DataSourceUtils.getDataSource());
        String sql ="update 用户表_ghw set 密码 = ? where id = ?";
        r.update(sql,user.get密码(),user.getId());
    }
    ...
}

3.2 UserService.java编写有关修改个人信息、密码的业务层方法

cn.ghw.service.UserService.java 增加有关登录的业务层方法

package cn.ghw.service;

public class UserService {
    private UserDao uDao = new UserDao();
    ...
    public void updateUserAddress(User user) {
        try {
            uDao.updateUserAddress(user);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void updatePwd(User user) {
        try {
            uDao.updatePwd(user);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    ...
}

3.3 编写有关修改个人信息、密码Servlet层方法

cn.ghw.servlet.UserChangeAddressServlet.java

package cn.ghw.servlet;

import cn.ghw.model.User;
import org.apache.commons.beanutils.BeanUtils;
import cn.ghw.service.UserService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

@WebServlet("/user_changeaddress")
public class UserChangeAddressServlet extends HttpServlet {

    private UserService uService = new UserService();

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        User loginUser = (User) request.getSession().getAttribute("user");
        try {
            BeanUtils.copyProperties(loginUser, request.getParameterMap());
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        uService.updateUserAddress(loginUser);
        request.setAttribute("msg", "收件信息更新成功!");
        request.getRequestDispatcher("/user_center.jsp").forward(request, response);
    }
}

cn.ghw.servlet.UserChangePwd.java

package cn.ghw.servlet;

import cn.ghw.model.User;
import cn.ghw.service.UserService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/user_changepwd")
public class UserChangePwd extends HttpServlet {

    private UserService uService = new UserService();

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String password = request.getParameter("password");
        String newPwd = request.getParameter("newPassword");

        User u = (User) request.getSession().getAttribute("user");
        if(password.equals(u.get密码())) {
            u.set密码(newPwd);
            uService.updatePwd(u);
            request.setAttribute("msg", "修改成功!");
            request.getRequestDispatcher("/user_center.jsp").forward(request, response);
        }else {
            request.setAttribute("failMsg", "修改失败,原密码不正确,你再想想!");
            request.getRequestDispatcher("/user_center.jsp").forward(request, response);
        }
    }
}

3.4 个人中心页面

web/user_center.jsp

<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
    <title>个人中心</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/bootstrap.css">
    <link rel="stylesheet" href="css/style.css">
    <script src="js/jquery.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script src="js/simpleCart.min.js"></script>
</head>
<body>

    <jsp:include page="/header.jsp">
        <jsp:param value="4" name="flag"/>
    </jsp:include>
    <c:if test="${empty user}"><%response.sendRedirect("/index");%></c:if>
    <!--account-->
    <div class="account">
        <div class="container">
            <div class="register">
                <c:if test="${!empty msg }">
                    <div class="alert alert-success">${msg }</div>
                </c:if>
                <c:if test="${!empty failMsg }">
                    <div class="alert alert-danger">${failMsg }</div>
                </c:if>

                    <div class="register-top-grid">
                        <h3>个人中心</h3>
                        <form action="user_changeaddress" method="post">
                        <!-- 收货信息 start -->
                        <h4>用户信息</h4>
                        <div class="input">
                            <span>姓名或名称<label></label></span>
                            <input type="text" name="名称" value="${user.名称 }" placeholder="请输入姓名或名称">
                        </div>
                        <div class="input">
                            <span>电话</span>
                            <input type="text" name="电话" value="${user.电话 }" placeholder="请输入电话">
                        </div>
                        <div class="input">
                            <span>地址</span>
                            <input type="text" name="地址" value="${user.地址 }" placeholder="请输入地址">
                        </div>
                        <div class="register-but text-center">
                           <input type="submit" value="提交">
                        </div>
                        <!-- 收货信息 end -->
                        </form>
                        <hr>
                        <form action="user_changepwd" method="post">
                        <h4>安全信息</h4>
                        <div class="input">
                            <span>原密码</span>
                            <input type="text" name="password" placeholder="请输入原密码">
                        </div>
                        <div class="input">
                            <span>新密码</span>
                            <input type="text" name="newPassword" placeholder="请输入新密码">
                        </div>
                        <div class="clearfix"> </div>
                        <div class="register-but text-center">
                           <input type="submit" value="提交">
                        </div>
                        </form>
                    </div>

                <div class="clearfix"> </div>
            </div>
        </div>
    </div>
    <!--//account-->

    <jsp:include page="footer.jsp"></jsp:include>
</body>
</html>
图10 个人中心界面

3.5 个人中心退出servlet

cn.ghw.servlet.UserLogoutServlet.java

package cn.ghw.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "user_logout",urlPatterns = {"/user_logout","/admin/user_logout"})
public class UserLogoutServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getSession().removeAttribute("user");
        //request.getRequestDispatcher("/index").forward(request, response);
        response.sendRedirect(request.getContextPath() +"/index");
    }
}

3.6 首页servlet

cn.ghw.servlet.IndexServlet.java 暂时注释有关GoodsService代码

package cn.ghw.servlet;

//import cn.ghw.service.GoodsService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;

@WebServlet("/index")
public class IndexServlet extends HttpServlet {
    //private GoodsService gService=new GoodsService();
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*List<Map<String,Object>> ScrollGood=gService.getScrollGood();
        request.setAttribute("scroll",ScrollGood);

        List<Map<String,Object>>newList=gService.getGoodsList(3);
        request.setAttribute("newList",newList);

        List<Map<String,Object>>hotList=gService.getGoodsList(2);
        request.setAttribute("hotList",hotList);*/

        //response.sendRedirect("index.jsp");
        request.getRequestDispatcher("index.jsp").forward(request,response);
    }
}

web/WEB-INF/web.xml

    <welcome-file-list>
        <welcome-file>index</welcome-file>
    </welcome-file-list>

4 商品分类

4.1 创建model

cn.ghw.model.Type.java 商品分类

package cn.ghw.model;

import lombok.Data;

@Data
public class Type {
    private int id;
    private String 名称;

    public Type() {
    }

    public Type(String 分类名称) {
        this.名称 = 分类名称;
    }

    public Type(int id, String 分类名称) {
        this.id = id;
        this.名称 = 分类名称;
    }
}

4.2 创建dao

cn.ghw.dao.TypeDao.java

package cn.ghw.dao;

import cn.ghw.model.Type;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import cn.ghw.utils.DataSourceUtils;

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

public class TypeDao{
    public List<Type> GetAllType() throws SQLException {
        QueryRunner r=new QueryRunner(DataSourceUtils.getDataSource());
        String sql="select * from 商品分类表_ghw";
        return r.query(sql,new BeanListHandler<Type>(Type.class));
    }
}

4.3 编写Service层方法

cn.ghw.service.TypeService.java

package cn.ghw.service;

import cn.ghw.dao.TypeDao;
import cn.ghw.model.Type;

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

public class TypeService {
    TypeDao tDao=new TypeDao();
    public List<Type> GetAllType() throws SQLException {
        List<Type> list=null;
        list=tDao.GetAllType();
        return list;
    }
}

4.4 编写ApplicationListener

cn.ghw.servlet.UserRegisterServlet.java

放开 第10,15行

package cn.ghw.listener;

import cn.ghw.service.TypeService;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener()
public class ApplicationListener implements ServletContextListener  {
     TypeService tsService=new TypeService();

    public void contextInitialized(ServletContextEvent sce) {
      /* 初始化servlet上下文时(部署Web应用程序时)调用此方法。
        您可以在这里初始化servlet上下文相关数据。*/
        sce.getServletContext().setAttribute("typeList",tsService.GetAllType());
    }
}

4.5 编写商品分类页面

web/header.jsp 页眉 25-33行

图11 商品分类

5 商品详情

5.1 创建model

cn.ghw.model.Goods.java 商品

package cn.ghw.model;

import lombok.Data;

@Data
public class Goods {
    private int id;
    private String 商品名称;
    private String 商品主图;
    private String 详情图1;
    private String 详情图2;
    private float 单价;
    private String 描述;
    private int 库存数量;
    private Type type;   //类型id

    private boolean isScroll;
    private boolean isHot;
    private boolean isNew;

    public boolean getIsScroll() {
        return isScroll;
    }

    public void setIsScroll(boolean scroll) {
        isScroll = scroll;
    }

    public boolean getIsHot() {
        return isHot;
    }

    public void setIsHot(boolean hot) {
        isHot = hot;
    }

    public boolean getIsNew() {
        return isNew;
    }

    public void setIsNew(boolean aNew) {
        isNew = aNew;
    }

    // 查询结果中有: 类型id 和 分类名称 两个字段,所有设计下列两个方法
    public void set类型id(int typeid) {
        if(type==null) {
            type = new Type();
        }
        type.setId(typeid);
    }
    public void set分类名称(String typename) {
        if(type==null) {
            type = new Type();
        }
        type.set名称(typename);
    }

    public Goods() {

    }

    public Goods(int id, String 商品名称, String 商品主图, String 详情图1, String 详情图2, float 单价, String 描述, int 库存数量,
            Type 商品分类) {
        super();
        this.id = id;
        this.商品名称 = 商品名称;
        this.商品主图 = 商品主图;
        this.详情图1 = 详情图1;
        this.详情图2 = 详情图2;
        this.单价 = 单价;
        this.描述 = 描述;
        this.库存数量 = 库存数量;
        this.type = 商品分类;
    }
}

5.2 创建dao

cn.ghw.dao.GoodsDao.java

package cn.ghw.dao;

import cn.ghw.model.Goods;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import cn.ghw.utils.DataSourceUtils;

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

public class GoodsDao{
    public Goods getGoodsById(int id) throws SQLException {
        QueryRunner r = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select g.id,g.商品名称,g.商品主图,g.详情图1,g.详情图2,g.单价,g.描述,g.库存数量,t.id 分类id,t.名称 分类名称 from 商品表_ghw g,商品分类表_ghw t where g.id = ? and g.类型id=t.id";
        return r.query(sql, new BeanHandler<Goods>(Goods.class),id);
    }
}

5.3 编写Service层方法

cn.ghw.service.GoodsService.java

package cn.ghw.service;

import cn.ghw.dao.GoodsDao;
import cn.ghw.model.Goods;
import java.sql.SQLException;

public class GoodsService {
    private GoodsDao gDao=new GoodsDao();

    public Goods getGoodsById(int id) {
        Goods g=null;
        try {
            g = gDao.getGoodsById(id);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return g;
    }
}

5.4 编写Servlet.

cn.ghw.servlet.GoodsDetailServlet.java

package cn.ghw.servlet;

import cn.ghw.model.Goods;
import cn.ghw.service.GoodsService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/goods_detail")
public class GoodsDetailServlet extends HttpServlet {

    private GoodsService gService = new GoodsService();
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int id = Integer.parseInt(request.getParameter("id"));
        Goods g = gService.getGoodsById(id);
        request.setAttribute("g", g);
        request.getRequestDispatcher("/goods_detail.jsp").forward(request, response);
    }
}

5.5 编写商品详情页面

web/goods_detail.jsp

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
    <title>商品详情</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/bootstrap.css">
    <link rel="stylesheet" href="css/style.css">
    <link rel="stylesheet" href="css/flexslider.css">

    <script src="js/jquery.min.js"></script>
    <script src="js/jquery.flexslider.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script src="layer/layer.js"></script>
    <script src="js/cart.js"></script>
    <script>
        $(function() {
          $('.flexslider').flexslider({
            animation: "slide",
            controlNav: "thumbnails"
          });
        });
    </script>
</head>
<body>

    <!--header-->
    <jsp:include page="header.jsp"></jsp:include>
    <!--//header-->

    <!--//single-page-->
    <div class="single">
        <div class="container">
            <div class="single-grids">
                <div class="col-md-4 single-grid">
                    <div class="flexslider">

                        <ul class="slides">
                            <li data-thumb="${g.商品主图}">
                                <div class="thumb-image"> <img src="${pageContext.request.contextPath }/${g.商品主图}" data-imagezoom="true" class="img-responsive"> </div>
                            </li>
                            <li data-thumb="${g.详情图1}">
                                <div class="thumb-image"> <img src="${pageContext.request.contextPath }/${g.详情图1}"  data-imagezoom="true" class="img-responsive"> </div>
                            </li>
                            <li data-thumb="${g.详情图2}">
                                <div class="thumb-image"> <img src="${pageContext.request.contextPath }/${g.详情图2}"  data-imagezoom="true" class="img-responsive"> </div>
                            </li>
                        </ul>
                    </div>
                </div>
                <div class="col-md-4 single-grid simpleCart_shelfItem">
                    <h3>${g.商品名称}</h3>
                    <div class="tag">
                        <p>分类 : <a href="goods_list?typeid=${g.type.id}">${g.type.名称}</a></p>
                    </div>
                    <p>${g.描述}</p>
                    <div class="galry">
                        <div class="prices">
                            <h5 class="item_price">¥ ${g.单价}</h5>
                        </div>
                        <div class="clearfix"></div>
                    </div>
                    <div class="btn_form">
                        <a href="javascript:;" class="add-cart item_add" onclick="buy(${g.id})">加入购物车</a>
                    </div>
                </div>
                <div class="col-md-4 single-grid1">
                    <!-- <h2>商品分类</h2> -->
                    <ul>
                        <li><a  href="goods_list">全部系列</a></li>

                        <c:forEach items="${typeList}" var="t">
                            <li><a href="goods_list?typeid=${t.id}">${t.名称}</a></li>
                        </c:forEach>
                    </ul>
                </div>
                <div class="clearfix"> </div>
            </div>
        </div>
    </div>

    <!--footer-->
    <jsp:include page="footer.jsp"></jsp:include>
    <!--//footer-->

</body>
</html>

http://localhost:8080/ch13_ghw/goods_detail?id=9

图12 商品详情

6 商品分类查询

6.1 创建model

cn.ghw.model.Page.java 分页

package cn.ghw.model;

import lombok.Data;
import java.util.List;

@Data
public class Page {
    private int pageNumber;
    private int pageSize;
    private int totalCount;
    private int totalPage;
    private List<Object> list;

    public void SetPageSizeAndTotalCount(int pageSize,int totalCount)
    {
        this.pageSize=pageSize;
        this.totalCount=totalCount;
        totalPage= (int)Math.ceil((double)totalCount/pageSize);
    }
}

6.2 创建dao--分类查询

cn.ghw.dao.TypeDao.java

package cn.ghw.dao;
...
public class TypeDao{
    ...
    public Type selectTypeNameByID(int typeid) throws SQLException {
        QueryRunner r=new QueryRunner(DataSourceUtils.getDataSource());
        String sql="select * from 商品分类表_ghw where id=?";
        return r.query(sql,new BeanHandler<Type>(Type.class),typeid);
    }
    ...
}

cn.ghw.dao.GoodsDao.java

package cn.ghw.dao;
...
public class Goods{
    ...
    public Type selectTypeNameByID(int typeid) throws SQLException {
        QueryRunner r=new QueryRunner(DataSourceUtils.getDataSource());
        String sql="select * from 商品分类表_ghw where id=?";
        return r.query(sql,new BeanHandler<Type>(Type.class),typeid);
    }

    // 某类型id商品 的 商品种类信息 -- count
    public int getCountOfGoodsByTypeID(int typeID) throws SQLException {
        String sql="";
        QueryRunner r=new QueryRunner(DataSourceUtils.getDataSource());
        if(typeID==0){
            sql="select count(*) from 商品表_ghw";
            return r.query(sql,new ScalarHandler<Long>()).intValue();
        }
        else{
            sql="select count(*) from 商品表_ghw where 类型id=?";
            return r.query(sql,new ScalarHandler<Long>(),typeID).intValue();
        }
    }
    ...
}

6.3 编写Service层方法--分类查询

cn.ghw.service.TypeService.java

package cn.ghw.service;
...
public class TypeService {
    private GoodsDao gDao=new GoodsDao();
    ...
    public Type selectTypeNameByID(int typeid){
        Type type=null;
        try {
            type=tDao.selectTypeNameByID(typeid);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return type;
    }
    // 某类型id商品 的 商品信息
    public List<Goods> selectGoodsByTypeID(int typeID,int pageNumber,int pageSize) throws SQLException {
        if(typeID==0){
            String sql="select * from 商品表_ghw limit ? , ?";
            QueryRunner r=new QueryRunner(DataSourceUtils.getDataSource());
            return  r.query(sql,new BeanListHandler<Goods>(Goods.class),(pageNumber-1)*pageSize,pageSize);
        }
        else {
            String sql="select * from 商品表_ghw where 类型id=? limit ? , ?";
            QueryRunner r=new QueryRunner(DataSourceUtils.getDataSource());
            return  r.query(sql,new BeanListHandler<Goods>(Goods.class),typeID,(pageNumber-1)*pageSize,pageSize);
        }
    }
    ...
}

cn.ghw.service.GoodsService.java

package cn.ghw.service;
...
public class GoodsService {
    private GoodsDao gDao=new GoodsDao();
    ...
    public Page selectPageByTypeID(int typeID, int pageNumber) {
        Page p=new Page();
        p.setPageNumber(pageNumber);
        int totalCount=0;
        try {
            totalCount=gDao.getCountOfGoodsByTypeID(typeID);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        p.SetPageSizeAndTotalCount(8,totalCount);

        List list=null;
        try {
            list=gDao.selectGoodsByTypeID(typeID,pageNumber,8);
        } catch (SQLException e) {
            e.printStackTrace();
        }

        p.setList(list);
        return p;
    }
    ...
}

6.4 编写Servlet.

cn.ghw.servlet.GoodsListServlet.java

package cn.ghw.servlet;

import cn.ghw.model.Page;
import cn.ghw.model.Type;
import cn.ghw.service.GoodsService;
import cn.ghw.service.TypeService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/goods_list")
public class GoodsListServlet extends HttpServlet {
    private GoodsService gService=new GoodsService();
    private TypeService tService=new TypeService();

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int id=0;
        if(request.getParameter("typeid")!=null)
        {
            id=Integer.parseInt(request.getParameter("typeid"));
        }
        int pageNumber=1;
        if(request.getParameter("pageNumber")!=null) {
            try {
                pageNumber=Integer.parseInt(request.getParameter("pageNumber"));
            }
            catch (Exception e)
            {

            }

        }
        Type t=null;
        if(id!=0)
        {
            t=tService.selectTypeNameByID(id);
        }
        request.setAttribute("t",t);
        //List<Goods> list=gService.selectGoodsByTypeID(id,1,8);
        //request.setAttribute("goodsList",list);
        if(pageNumber<=0)
            pageNumber=1;
        Page p=gService.selectPageByTypeID(id,pageNumber);

        if(p.getTotalPage()==0)
        {
            p.setTotalPage(1);
            p.setPageNumber(1);
        }
        else {
            if(pageNumber>=p.getTotalPage()+1)
            {
                p=gService.selectPageByTypeID(id,p.getTotalPage());
            }
        }

        request.setAttribute("p",p);
        request.setAttribute("id",String.valueOf(id));
        request.getRequestDispatcher("/goods_list.jsp").forward(request,response);
    }
}

6.5 编写商品分类查询页面

web/page.jsp

<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<div style='text-align:center;'>
    <a class='btn btn-info' <c:if test="${p.pageNumber==1 }">disabled</c:if>
       <c:if test="${p.pageNumber!=1 }">href="${param.url }?pageNumber=1${param.param }"</c:if>>首页</a>
    <a class='btn btn-info' <c:if test="${p.pageNumber==1 }">disabled</c:if>
       <c:if test="${p.pageNumber!=1 }">href="${param.url }?pageNumber=${p.pageNumber-1}${param.param }"</c:if>>上一页</a>
    <h3 style='display:inline;'>[${p.pageNumber }/${p.totalPage }]</h3>
    <h3 style='display:inline;'>[${p.totalCount }]</h3>
    <a class='btn btn-info' <c:if test="${p.totalPage==0 || p.pageNumber==p.totalPage }">disabled</c:if>
       <c:if test="${p.pageNumber!=p.totalPage }">href="${param.url }?pageNumber=${p.pageNumber+1}${param.param }"</c:if>>下一页</a>
    <a class='btn btn-info' <c:if test="${p.totalPage==0 || p.pageNumber==p.totalPage }">disabled</c:if>
       <c:if test="${p.pageNumber!=p.totalPage }">href="${param.url }?pageNumber=${p.totalPage}${param.param }"</c:if>>尾页</a>
    <input type='text' class='form-control' style='display:inline;width:60px;' value=''/>
    <a class='btn btn-info' href='javascript:void(0);'
       onclick='location.href="${param.url }?pageNumber="+(this.previousSibling.value)+"${param.param }"'>GO</a>
</div>

web/goods_list.jsp

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
    <title>首页</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/bootstrap.css">
    <link rel="stylesheet" href="css/style.css">
    <script src="js/jquery.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script src="js/simpleCart.min.js"></script>
    <script src="layer/layer.js"></script>
    <script src="js/cart.js"></script>
</head>
<body>

<!--header-->
<jsp:include page="header.jsp">
    <jsp:param name="flag" value="2"></jsp:param>
</jsp:include>
<!--//header-->

<!--proghwcts-->
<div class="proghwcts">
    <div class="container">
        <h2><c:choose><c:when test="${empty t}">全部系列</c:when><c:otherwise>${t.名称}</c:otherwise> </c:choose></h2>

        <div class="col-md-12 proghwct-model-sec">

            <c:forEach items="${p.list}" var="g">
                <div class="proghwct-grid">
                    <a href="goods_detail?id=${g.id}">
                        <div class="more-proghwct"><span> </span></div>
                        <div class="proghwct-img b-link-stripe b-animate-go  thickbox">
                            <img src="${g.商品主图}" class="img-responsive" alt="${g.商品名称}" width="240" height="240">
                            <div class="b-wrapper">
                                <h4 class="b-animate b-from-left  b-delay03">
                                    <button href="goods_detail?id=${g.id}">查看详情</button>
                                </h4>
                            </div>
                        </div>
                    </a>
                    <div class="proghwct-info simpleCart_shelfItem">
                        <div class="proghwct-info-cust prt_name">
                            <h4>${g.商品名称}</h4>
                            <span class="item_price">¥ ${g.单价}</span>
                            <input type="button" class="item_add items" value="加入购物车" onclick="buy(${g.id})">
                            <div class="clearfix"> </div>
                        </div>
                    </div>
                </div>
            </c:forEach>

        </div>

        <jsp:include page="page.jsp">
            <jsp:param name="url" value="goods_list"></jsp:param>
            <jsp:param name="param" value="&typeid=${id}"></jsp:param>
        </jsp:include>
        </div>
    </div>
</div>
<!--//proghwcts-->


<!--footer-->
<jsp:include page="footer.jsp"></jsp:include>
<!--//footer-->

</body>
</html>
图13 商品分类查询

7 商品推荐(热销、新品)

图14 热销商品
图15 新品

7.1 创建model

cn.ghw.model.Recommend.java 推荐; //1轮播 2热销 3新品

package cn.ghw.model;
import lombok.Data;

@Data
public class Recommend {
    private int id;
    private int 推荐类别;   //1轮播 2热销 3新品
    private Goods goods;

    public Recommend(int id, int 推荐类别, Goods goods) {
        this.id = id;
        this.推荐类别 = 推荐类别;
        this.goods = goods;
    }

    public Recommend() {

    }

}

7.2 创建dao--分类查询

cn.ghw.dao.GoodsDao.java

package cn.ghw.dao;
...
public class GoodsDao{
    ...
    // 推荐商品
    public List<Map<String,Object>> getGoodsList(int recommendType) throws SQLException {
        QueryRunner r = new QueryRunner(DataSourceUtils.getDataSource());
        String sql="select g.id,g.商品名称,g.商品主图,g.单价,t.名称 分类名称 from 推荐商品表_ghw r,商品表_ghw g,商品分类表_ghw t where 推荐类别=? and r.商品id=g.id and g.类型id=t.id";
        return r.query(sql, new MapListHandler(),recommendType);
    }

    // 轮播商品
    public List<Map<String,Object>> getScrollGood()throws SQLException{
        QueryRunner r = new QueryRunner(DataSourceUtils.getDataSource());
        String sql="select g.id,g.商品名称,g.商品主图,g.单价 from 推荐商品表_ghw r,商品表_ghw g where 推荐类别=1 and r.商品id=g.id";
        return r.query(sql, new MapListHandler());
    }}

   // 商品名称,商品主图,详情图1,详情图2,单价,描述,库存数量,类型id
    public List<Goods> selectGoodsbyRecommend(int type,int pageNumber,int pageSize) throws SQLException {
        QueryRunner r = new QueryRunner(DataSourceUtils.getDataSource());
        if(type==0) {
            //当不添加推荐类型限制的时候
            String sql = " select g.id,g.商品名称,g.商品主图,g.详情图1,g.详情图2,g.描述,g.单价,g.库存数量,t.名称 分类名称 from 商品表_ghw g,商品分类表_ghw t where g.类型id=t.id order by g.id limit ?,?";
            return r.query(sql, new BeanListHandler<Goods>(Goods.class),(pageNumber-1)*pageSize,pageSize);
        }

        String sql = " select g.id,g.商品名称,g.商品主图,g.详情图1,g.详情图2,g.描述,g.单价,g.库存数量,t.名称 分类名称 from 商品表_ghw g,推荐商品表_ghw r,商品分类表_ghw t where g.id=r.商品id and g.类型id=t.id and r.推荐类别=? order by g.id limit ?,?";
        return r.query(sql, new BeanListHandler<Goods>(Goods.class),type,(pageNumber-1)*pageSize,pageSize);
    }

    public int getRecommendCountOfGoodsByTypeID(int type) throws SQLException {
        if(type==0)return getCountOfGoodsByTypeID(0);
        QueryRunner r = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select count(*) from 推荐商品表_ghw where 推荐类别=?";
        return r.query(sql, new ScalarHandler<Long>(),type).intValue();
    }

    public boolean isScroll(Goods g) throws SQLException {
        return isRecommend(g, 1);
    }

    // 判断是否是 热销商品
    public boolean isHot(Goods g) throws SQLException {
        return isRecommend(g, 2);
    }

    // 判断是否是 新上架商品
    public boolean isNew(Goods g) throws SQLException {
        return isRecommend(g, 3);
    }

    // 判断是否是某推荐类别商品
    private boolean isRecommend(Goods g,int type) throws SQLException {
        QueryRunner r = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select * from 推荐商品表_ghw where 推荐类别=? and 商品id=?";
        Recommend recommend = r.query(sql, new BeanHandler<Recommend>(Recommend.class),type,g.getId());
        if(recommend==null)
            return false;
        else
            return true;
    }
    ...
}

7.3 编写Service层方法--分类查询

cn.ghw.service.GoodsService.java

package cn.ghw.service;
...
public class GoodsService {
    private GoodsDao gDao=new GoodsDao();
    ...
    public Page selectPageByTypeID(int typeID, int pageNumber) {
        Page p=new Page();
        p.setPageNumber(pageNumber);
        int totalCount=0;
        try {
            totalCount=gDao.getCountOfGoodsByTypeID(typeID);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        p.SetPageSizeAndTotalCount(8,totalCount);

        List list=null;
        try {
            list=gDao.selectGoodsByTypeID(typeID,pageNumber,8);
        } catch (SQLException e) {
            e.printStackTrace();
        }

        p.setList(list);
        return p;
    }

    public Page getGoodsRecommendPage(int type,int pageNumber) {
        Page p = new Page();
        p.setPageNumber(pageNumber);
        int totalCount = 0;
        try {
            totalCount = gDao.getRecommendCountOfGoodsByTypeID(type);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        p.SetPageSizeAndTotalCount(8, totalCount);
        List list=null;
        try {
            list = gDao.selectGoodsbyRecommend(type, pageNumber, 8);
            for(Goods g : (List<Goods>)list) {
                g.setIsScroll(gDao.isScroll(g));
                g.setIsHot(gDao.isHot(g));
                g.setIsNew(gDao.isNew(g));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        p.setList(list);
        return p;
    }

    public List<Map<String,Object>> getGoodsList(int recommendType) {
        List<Map<String,Object>> list=null;
        try {
            list=gDao.getGoodsList(recommendType);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }

    public List<Map<String,Object>> getScrollGood() {
        List<Map<String,Object>> list=null;
        try {
            list=gDao.getScrollGood();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }
    ...
}

7.4 编写Servlet.

cn.ghw.servlet.GoodRecommendListServlet.java

ppackage cn.ghw.servlet;

import cn.ghw.model.Page;
import cn.ghw.service.GoodsService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/goodsrecommend_list")
public class GoodRecommendListServlet extends HttpServlet {
    private GoodsService gService = new GoodsService();

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int type = Integer.parseInt(request.getParameter("type") ) ;
        int pageNumber = 1;
        if(request.getParameter("pageNumber") != null) {
            try {
                pageNumber=Integer.parseInt(request.getParameter("pageNumber") ) ;
            }
            catch (Exception e)
            {

            }
        }
        if(pageNumber<=0)
            pageNumber=1;
        Page p = gService.getGoodsRecommendPage(type, pageNumber);

        if(p.getTotalPage()==0)
        {
            p.setTotalPage(1);
            p.setPageNumber(1);
        }
        else {
            if(pageNumber>=p.getTotalPage()+1)
            {
                p = gService.getGoodsRecommendPage(type, p.getTotalPage());
            }
        }
        request.setAttribute("p", p);
        request.setAttribute("t", type);
        request.getRequestDispatcher("goodsrecommend_list.jsp").forward(request, response);
    }
}

7.5 编写推荐商品分类查询页面

web/goodsrecommend_list.jsp

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
    <title>首页</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/bootstrap.css">
    <link rel="stylesheet" href="css/style.css">
    <script src="js/jquery.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script src="js/simpleCart.min.js"></script>
    <script src="layer/layer.js"></script>
    <script src="js/cart.js"></script>
</head>
<body>

<!--header-->
<jsp:include page="header.jsp">
    <jsp:param name="flag" value="3"></jsp:param>
</jsp:include>
<!--//header-->

<!--proghwcts-->
<div class="proghwcts">
    <div class="container">
        <h2><c:choose><c:when test="${t==2}">热销商品</c:when><c:otherwise>新品商品</c:otherwise></c:choose></h2>

        <div class="col-md-12 proghwct-model-sec">

            <c:forEach items="${p.list}" var="g">
                <div class="proghwct-grid">
                    <a href="goods_detail?id=${g.id}">
                        <div class="more-proghwct"><span> </span></div>
                        <div class="proghwct-img b-link-stripe b-animate-go  thickbox">
                            <img src="${g.商品主图}" class="img-responsive" alt="${g.商品名称}" width="240" height="240">
                            <div class="b-wrapper">
                                <h4 class="b-animate b-from-left  b-delay03">
                                    <button href="/goods_detail?id=${g.id}">查看详情</button>
                                </h4>
                            </div>
                        </div>
                    </a>
                    <div class="proghwct-info simpleCart_shelfItem">
                        <div class="proghwct-info-cust prt_name">
                            <h4>${g.商品名称}</h4>
                            <span class="item_price">¥ ${g.单价}</span>
                            <input type="button" class="item_add items" value="加入购物车" onclick="buy(${g.id})">
                            <div class="clearfix"> </div>
                        </div>
                    </div>
                </div>
            </c:forEach>
        </div>

        <jsp:include page="page.jsp">
            <jsp:param name="url" value="goodsrecommend_list"></jsp:param>
            <jsp:param name="param" value="&type=${t}"></jsp:param>
        </jsp:include>
        </div>
    </div>
</div>
<!--//proghwcts-->

<!--footer-->
<jsp:include page="footer.jsp"></jsp:include>
<!--//footer-->

</body>
</html>

cn.ghw.servlet.IndexServlet.java 放开有关GoodsService代码

package cn.ghw.servlet;

import cn.ghw.service.GoodsService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;

@WebServlet("/index")
public class IndexServlet extends HttpServlet {
    private GoodsService gService=new GoodsService();
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        List<Map<String,Object>> ScrollGood=gService.getScrollGood();
        request.setAttribute("scroll",ScrollGood);

        List<Map<String,Object>>newList=gService.getGoodsList(3);
        request.setAttribute("newList",newList);

        List<Map<String,Object>>hotList=gService.getGoodsList(2);
        request.setAttribute("hotList",hotList);

        //response.sendRedirect("index.jsp");
        request.getRequestDispatcher("index.jsp").forward(request,response);
    }
}
图16 热销
图17 新品

8 商品搜索功能

8.1 创建dao--搜索功能

cn.ghw.dao.GoodsDao.java

package cn.ghw.dao;
...
public class GoodsDao{
    ...
    // 查询 商品名称 中 包含 关键字 的 商品种数 -- count
    public int getSearchCount(String keyword) throws SQLException {
        QueryRunner r = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select count(*) from 商品表_ghw where 商品名称 like ?";
        return r.query(sql, new ScalarHandler<Long>(),"%"+keyword+"%").intValue();
    }

    // 分页查询 商品名称 中 包含 关键字 的 商品信息
    public List<Goods> selectSearchGoods(String keyword, int pageNumber, int pageSize) throws SQLException{
        QueryRunner r = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select * from 商品表_ghw where 商品名称 like ? limit ?,?";
        return r.query(sql, new BeanListHandler<Goods>(Goods.class),"%"+keyword+"%",(pageNumber-1)*pageSize,pageSize);
    }
    ...
}

8.2 编写Service层方法--分类查询

cn.ghw.service.GoodsService.java

package cn.ghw.service;
...
public class GoodsService {
    private GoodsDao gDao=new GoodsDao();
    ...
    public Page getSearchGoodsPage(String keyword, int pageNumber) {
        Page p = new Page();
        p.setPageNumber(pageNumber);
        int totalCount = 0;
        try {
//            totalCount = gDao.getGoodsCount(typeId);
            totalCount = gDao.getSearchCount(keyword);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        p.SetPageSizeAndTotalCount(8, totalCount);
        List list=null;
        try {
//            list = gDao.selectGoods(keyword, pageNo, 8);
            list = gDao.selectSearchGoods(keyword,pageNumber,8);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        p.setList(list);
        return p;
    }
    ...
}

8.3 编写Servlet.

cn.ghw.servlet.GoodsSearchServlet.java

package cn.ghw.servlet;

import cn.ghw.model.Page;
import cn.ghw.service.GoodsService;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;

@WebServlet("/goods_search")
public class GoodsSearchServlet extends HttpServlet {
    private GoodsService gService = new GoodsService();
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String keyword = request.getParameter("keyword");
        int pageNumber = 1;
        if(request.getParameter("pageNumber") != null) {
            try {
                pageNumber=Integer.parseInt(request.getParameter("pageNumber") ) ;
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
        if(pageNumber<=0)
            pageNumber=1;

        Page p =gService.getSearchGoodsPage(keyword,pageNumber);

        if(p.getTotalPage()==0){
            p.setTotalPage(1);
            p.setPageNumber(1);
        } else {
            if(pageNumber>=p.getTotalPage()+1)
                p =gService.getSearchGoodsPage(keyword,pageNumber);
        }
        request.setAttribute("p", p);
        request.setAttribute("keyword", URLEncoder.encode(keyword,"utf-8"));
        request.getRequestDispatcher("/goods_search.jsp").forward(request, response);
    }
}

8.4 编写商品搜索查询页面

web/goods_search.jsp

<%@ page language="java" contentType="text/html; charset=utf-8"
         pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<!DOCTYPE html>
<html>
<head>
    <title>首页</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/bootstrap.css">
    <link rel="stylesheet" href="css/style.css">
    <script src="js/jquery.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script src="js/simpleCart.min.js"></script>
    <script src="layer/layer.js"></script>
    <script src="js/cart.js"></script>
</head>
<body>

<jsp:include page="/header.jsp">
    <jsp:param value="8" name="flag"/>
</jsp:include>

<!--proghwcts-->
<div class="proghwcts">
    <div class="container">
        <h2> 搜索 ‘${param.keyword }’的结果 </h2>

        <div class="col-md-12 proghwct-model-sec">

            <c:forEach items="${p.list }" var="g">
                <div class="proghwct-grid">
                    <a href="${pageContext.request.contextPath }/goods_detail?id=${g.id}">
                        <div class="more-proghwct"><span> </span></div>
                        <div class="proghwct-img b-link-stripe b-animate-go  thickbox">
                            <img src="${pageContext.request.contextPath }/${g.商品主图}" class="img-responsive" alt="${g.商品名称 }" width="240" height="240">
                            <div class="b-wrapper">
                                <h4 class="b-animate b-from-left  b-delay03">
                                    <button>查看详情</button>
                                </h4>
                            </div>
                        </div>
                    </a>
                    <div class="proghwct-info simpleCart_shelfItem">
                        <div class="proghwct-info-cust prt_name">
                            <h4>${g.商品名称 }</h4>
                            <span class="item_price">¥ ${g.单价 }</span>
                            <input type="button" class="item_add items" value="加入购物车" onclick="buy(${g.id})">
                            <div class="clearfix"> </div>
                        </div>
                    </div>
                </div>
            </c:forEach>

            <div class="clearfix"> </div>
        </div>
        <div>
            <jsp:include page="page.jsp">
                <jsp:param name="url" value="goods_search"/>
                <jsp:param name="param" value="&keyword=${keyword}"/>
            </jsp:include>
        </div>
    </div>
</div>
<!--//proghwcts-->

<jsp:include page="footer.jsp"/>

</body>
</html>

8.5 编写商品搜索界面

web/header.jsp 页眉 60-68行

在首页进行搜索

图18 商品搜索

9 购物车功能(增加、减少、删除)

图19 购物车功能

此处实现上述功能中的添加商品到购物车、自动更新商品数量与总价格和删除购物车中单件商品前4项功能。

购物车信息存储:session域的order属性,不改变数据库中的数据
Order o = (Order) request.getSession().getAttribute("order");
功能 入口(goods_cart.jsp) js(cart.js) servlet model(Order.java)
增加 <a class="btn btn-info" href="javascript: buy(${item.key});">增加</a> buy(goodid)
$.post("goods_buy", {goodsid:goodid},...}
GoodsBuyServlet
g=gService.getGoodsById(goodsid);
o.addGoods(g)
addGoods
(Goods g)
减少 <a class="btn btn-warning" href="javascript: lessen(${item.key});">减少</a> lessen(goodsid)
$.post("goods_lessen", {goodsid:goodsid},...}
GoodsLessenServlet
gid=req.getParameter("goodsid");
o.lessen(gid)
lessen
(int goodsid)
删除 <a class="btn btn-danger" href="javascript: deletes(${item.key});">删除</a> deletes(goodid){
$.post("goods_delete",{goodsid:goodid},...}
GoodsDeleteServlet
gid=req.getParameter("goodsid");
o.delete(gid)
delete
(int goodsid)

仅有GoodsBuyServlet.java用到service层的gService.getGoodsById(gid)。

9.1 购物车model层

(1) cn.ghw.model.Order.java 订单

package cn.ghw.model;

import cn.ghw.utils.PriceUtils;
import java.util.*;
import lombok.Data;

@Data
public class Order {
    private int id;
    private float 总额;
    private int 商品总数;
    private int 订单状态;  //1未付款/2已付款/3已发货/4已完成
    private int 支付方式;  //1微信/2支付宝/3货到付款
    private String 收货人名称;
    private String 收货电话;
    private String 收货地址;
    private Date 下单时间;
    private User user;

    // 订单之订单项 Map | List
    private Map<Integer,OrderItem> itemMap = new HashMap<Integer,OrderItem>();
    private List<OrderItem> itemList = new ArrayList<OrderItem>();

    // select 语句返回 用户名 数据,写入 user.用户名
    public void set用户名(String 用户名) {
        user = new User();
        user.set用户名(用户名);
    }

    // 添加 商品  + 1
    public void addGoods(Goods g) {
        if(itemMap.containsKey(g.getId())) {
            OrderItem item = itemMap.get(g.getId());
            item.set数量(item.get数量()+1);
        }else {
            OrderItem item = new OrderItem(g.get单价(),1,g,this);
            itemMap.put(g.getId(), item);
        }
        商品总数++;
        总额 = PriceUtils.add(总额, g.get单价());
    }

    // 减少 订单项 -1
    public void lessen(int goodsid) {
        if(itemMap.containsKey(goodsid)) {
            OrderItem item = itemMap.get(goodsid);
            item.set数量(item.get数量()-1);
            商品总数--;
            总额 = PriceUtils.subtract(总额, item.get单价());
            if(item.get数量()<=0) {
                itemMap.remove(goodsid);
            }
        }
    }

    // 删除订单项
    public void delete(int goodsid){
        if(itemMap.containsKey(goodsid)) {
            OrderItem item = itemMap.get(goodsid);
            总额 = PriceUtils.subtract(总额, item.get数量()*item.get单价());
            商品总数-=item.get数量();
            itemMap.remove(goodsid);
        }
    }

    public Order() {

    }
}

(2) OrderItem.java 订单项

package cn.ghw.model;
import lombok.Data;

@Data
public class OrderItem {
    private int id;
    private float 单价;
    private int 数量;
    private String 商品名称;
    private Goods goods;
    private Order order;// order_id

    public OrderItem() {

    }

    public OrderItem(float 单价, int 数量, Goods goods, Order order) {
        this.单价 = 单价;
        this.数量 = 数量;
        this.goods = goods;
        this.order = order;
    }
}

9.2 购物车控制层

(1) GoodsBuyServlet.java 添加购物车

package cn.ghw.servlet;

import cn.ghw.model.Goods;
import cn.ghw.model.Order;
import cn.ghw.service.GoodsService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/goods_buy")
public class GoodsBuyServlet extends HttpServlet {
    private GoodsService gService = new GoodsService();
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.声明车
        Order o = null;
        if(request.getSession().getAttribute("order") != null) {
            // 第二次 有了   获取
            o = (Order) request.getSession().getAttribute("order");
        }else {
            // 第一次 没有车 创建
            o = new Order();
            request.getSession().setAttribute("order", o);
        }
        //3.获取前台的参数goodsid 查询商品信息
        int goodsid = Integer.parseInt(request.getParameter("goodsid"));
        Goods goods = gService.getGoodsById(goodsid);
        //4.加入购物车库存问题
        if(goods.get库存数量()>0) {
            o.addGoods(goods);
            response.getWriter().print("ok");
        }else {
            response.getWriter().print("fail");
        }
    }
}

(2) GoodsLessenServlet.java 减少数量和总价

package cn.ghw.servlet;

import cn.ghw.model.Order;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/goods_lessen")
public class GoodsLessenServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Order o = (Order) request.getSession().getAttribute("order");
        int goodsid = Integer.parseInt(request.getParameter("goodsid"));
        o.lessen(goodsid);
        response.getWriter().print("ok");
    }
}

(3) GoodsDeleteServlet.java 删除购物车中商品

package cn.ghw.servlet;

import cn.ghw.model.Order;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/goods_delete")
public class GoodsDeleteServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 拿到购物车对象
        Order o = (Order) request.getSession().getAttribute("order");
        // 拿到商品id
        int goodsid = Integer.parseInt(request.getParameter("goodsid"));
        // 删除
        o.delete(goodsid);
        // 响应
        response.getWriter().print("ok");
    }
}

9.5 购物车界面

web/js/cart.js

/**
 * 加入购物车
 */
function buy(goodid){
    $.post("goods_buy", {goodsid:goodid}, function(data){
        if(data==="ok"){
            layer.msg("添加到购物车!", {time:800}, function(){
               location.reload();
            });
        }
        else if(data==="fail"){
            layer.msg("库存不足,请购买其他商品!", {time:800}, function(){

            });
        }
        /*if(data=="ok"){
            layer.msg("操作成功!", {time:800}, function(){
                location.reload();
            });
        }else if(data=="login"){
            alert("请登录后购买!");
            location.href="login.jsp";
        }else if(data=="empty"){
            alert("库存不足!");
            location.reload();
        }else{
            alert("请求失败!");
        }*/

    });
}

/**
 * 减少购物车
 */
function lessen(goodsid){
    $.post("goods_lessen", {goodsid:goodsid}, function(data){
        if(data==="ok"){
            layer.msg("操作成功!", {time:800}, function(){
                location.reload();
            });
        }
//        if(data=="ok"){
//            layer.msg("操作成功!", {time:800}, function(){
//                location.href="cart.action";
//            });
//        }else if(data=="login"){
//            alert("请登录后操作!");
//            location.href="login.jsp";
//        }else{
//            alert("请求失败!");
//        }
    });
}

/**
 * 购物车删除
 */
function deletes(goodid){
    $.post("goods_delete", {goodsid:goodid}, function(data){
        if(data==="ok"){
            layer.msg("删除成功!", {time:800}, function(){
                location.reload();
            });
        }
    });
}

goods_cart.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<!DOCTYPE html>
<html>
<head>
    <title>购物车</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/bootstrap.css">
    <link rel="stylesheet" href="css/style.css">
    <script src="js/jquery.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script src="layer/layer.js"></script>
    <script src="js/cart.js"></script>
</head>
<body>
    <!--header-->
    <jsp:include page="/header.jsp">
        <jsp:param name="flag" value="7"/>
    </jsp:include>
    <!--//header-->

    <!--cart-items-->
    <div class="cart-items">
        <div class="container">

            <h2>我的购物车</h2>

            <c:forEach items="${order.itemMap }" var="item">
                <div class="cart-header col-md-6">
                    <div class="cart-sec simpleCart_shelfItem">
                        <div class="cart-item cyc">
                            <a href="goods_detail?id=${item.key}">
                                <img src="${pageContext.request.contextPath }/${item.value.goods.商品主图}" class="img-responsive">
                            </a>
                        </div>
                        <div class="cart-item-info">
                            <h3><a href="goods_detail?id=${item.key}">${item.value.goods.商品名称}</a></h3>
                            <h3><span>单价: ¥ ${item.value.单价}</span></h3>
                            <h3><span>数量: ${item.value.数量}</span></h3>
                            <a class="btn btn-info" href="javascript:buy(${item.key});">增加</a>
                            <a class="btn btn-warning" href="javascript:lessen(${item.key});">减少</a>
                            <a class="btn btn-danger" href="javascript:deletes(${item.key});">删除</a>
                        </div>
                        <div class="clearfix"></div>
                    </div>
                </div>
            </c:forEach>

            <div class="cart-header col-md-12">
                <hr>
                <h3>订单总金额: ¥ ${order.总额}</h3>
                <a class="btn btn-success btn-lg" style="margin-left:74%" href="order_submit">提交订单</a>
            </div>
        </div>
    </div>
    <!--//cart-items-->

    <!--footer-->
    <jsp:include page="footer.jsp"/>
    <!--//footer-->

</body>
</html>
图20 购物车界面

10 订单提交

图21 购物流程

我的购物车(goods_cart.jsp) 【提交订单】= => 提交订单 (order_submit.jsp)确认收货信息 和 支付方式 【确认订单】 = => 确认订单(order_success.jsp)

10.1 订单数据访问层

cn.ghw.dao.OrderDao.java

package cn.ghw.dao;

import cn.ghw.model.Order;
import cn.ghw.model.OrderItem;
import cn.ghw.utils.DataSourceUtils;
import org.apache.commons.dbutils.*;

import java.math.BigInteger;
import java.sql.*;
import java.util.*;
import org.apache.commons.dbutils.handlers.*;

public class OrderDao {

    // 添加订单
    public void insertOrder(Connection con, Order order) throws SQLException {
        QueryRunner r = new QueryRunner();
        String sql = "insert into 订单表_ghw(总额,商品总数,订单状态,支付方式,收货人名称,收货电话,收货地址,下单时间,用户id) values(?,?,?,?,?,?,?,?,?)";
        r.update(con,sql,
                order.get总额(),order.get商品总数(),order.get订单状态(),
                order.get支付方式(),order.get收货人名称(),order.get收货电话(),
                order.get收货地址(),order.get下单时间(),order.getUser().getId() );
    }

    // 查询最近插入的 自增id
    public int getLastInsertId(Connection con) throws SQLException {
        QueryRunner r = new QueryRunner();
        String sql = "select last_insert_id()";
        BigInteger bi = r.query(con, sql,new ScalarHandler<BigInteger>());
        return Integer.parseInt(bi.toString());
    }

    // 添加订单项
    public void insertOrderItem(Connection con, OrderItem item) throws SQLException {
        QueryRunner r = new QueryRunner();
        String sql ="insert into 订单项表_ghw(单价,数量,商品id,订单id) values(?,?,?,?)";
        r.update(con,sql,item.get单价(),item.get数量(),item.getGoods().getId(),item.getOrder().getId());
    }

    // 查询某 用户id 的所有订单
    public List<Order> selectAll(int userid) throws SQLException {
        QueryRunner r = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select * from 订单表_ghw where 用户id=? order by 下单时间 desc";
        return r.query(sql, new BeanListHandler<Order>(Order.class),userid);
    }

    // 查询某 订单id 的所有订单项
    public List<OrderItem> selectAllItem(int orderid) throws SQLException{
        QueryRunner r = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "select i.id,i.单价,i.数量,g.商品名称 from 订单项表_ghw i,商品表_ghw g where 订单id=? and i.商品id=g.id";
        return r.query(sql, new BeanListHandler<OrderItem>(OrderItem.class),orderid);
    }

    public int getOrderCount(int status) throws SQLException {
        QueryRunner r = new QueryRunner(DataSourceUtils.getDataSource());
        String sql = "";
        if(status==0) {
            sql = "select count(*) from 订单表_ghw";
            return r.query(sql, new ScalarHandler<Long>()).intValue();
        }else {
            sql = "select count(*) from 订单表_ghw where 订单状态=?";
            return r.query(sql, new ScalarHandler<Long>(),status).intValue();
        }
    }

    public List<Order> selectOrderList(int status, int pageNumber, int pageSize) throws SQLException {
        QueryRunner r = new QueryRunner(DataSourceUtils.getDataSource());
        if(status==0) {
            String sql = "select o.id,o.总额,o.商品总数,o.订单状态,o.支付方式,o.收货人名称,o.收货电话,o.收货地址,o.下单时间,u.用户名 from 订单表_ghw o, 用户表_ghw u where o.用户id=u.id order by o.下单时间 desc limit ?,?";
            return r.query(sql, new BeanListHandler<Order>(Order.class), (pageNumber-1)*pageSize,pageSize );
        }else {
            String sql = "select o.id,o.总额,o.商品总数,o.订单状态,o.支付方式,o.收货人名称,o.收货电话,o.收货地址,o.下单时间,u.用户名 from 订单表_ghw o,用户表_ghw u where o.用户id=u.id and o.订单状态=? order by o.下单时间 desc limit ?,?";
            return r.query(sql, new BeanListHandler<Order>(Order.class),status, (pageNumber-1)*pageSize,pageSize );
        }
    }

    public void updateStatus(int id,int status) throws SQLException {
        QueryRunner r = new QueryRunner(DataSourceUtils.getDataSource());
        String sql ="update 订单表_ghw set 订单状态=? where id = ?";
        r.update(sql,status,id);
    }

    public void deleteOrder(Connection con ,int id) throws SQLException {
        QueryRunner r = new QueryRunner();
        String sql ="delete from 订单表_ghw where id = ?";
        r.update(con,sql,id);
    }

    public void deleteOrderItem(Connection con ,int id) throws SQLException {
        QueryRunner r = new QueryRunner();
        String sql ="delete from 订单项表_ghw where 订单id=?";
        r.update(con,sql,id);
    }
}

10.2 订单业务层

OrderService.java

package cn.ghw.service;

import cn.ghw.dao.OrderDao;
import cn.ghw.model.Order;
import cn.ghw.model.OrderItem;
import cn.ghw.model.Page;
import cn.ghw.utils.DataSourceUtils;

import java.sql.*;
import java.util.List;

public class OrderService {
    private OrderDao oDao = new OrderDao();
    public void addOrder(Order order) {
        Connection con = null;
        try {
            con = DataSourceUtils.getConnection();
            con.setAutoCommit(false);

            oDao.insertOrder(con, order);
            int id = oDao.getLastInsertId(con);
            order.setId(id);
            for(OrderItem item : order.getItemMap().values()) {
                oDao.insertOrderItem(con, item);
            }

            con.commit();
        } catch (SQLException e) {
            e.printStackTrace();
            if(con!=null)
                try {
                    con.rollback();
                } catch (SQLException e1) {
                     e1.printStackTrace();
                }
        }
    }

    public List<Order> selectAll(int userid){
        List<Order> list=null;
        try {
            list = oDao.selectAll(userid);
            for(Order o :list) {
                List<OrderItem> l = oDao.selectAllItem(o.getId());
                o.setItemList(l);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }

    public Page getOrderPage(int status, int pageNumber) {
        Page p = new Page();
        p.setPageNumber(pageNumber);
        int pageSize = 10;
        int totalCount = 0;
        try {
            totalCount = oDao.getOrderCount(status);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        p.SetPageSizeAndTotalCount(pageSize, totalCount);
        List list=null;
        try {
            list = oDao.selectOrderList(status, pageNumber, pageSize);
            for(Order o :(List<Order>)list) {
                List<OrderItem> l = oDao.selectAllItem(o.getId());
                o.setItemList(l);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        p.setList(list);
        return p;
    }

    public void updateStatus(int id,int status) {
        try {
            oDao.updateStatus(id, status);
        } catch (SQLException e) {
             e.printStackTrace();
        }
    }
    public void delete(int id) {
        Connection con = null;
        try {
            con = DataSourceUtils.getDataSource().getConnection();
            con.setAutoCommit(false);

            oDao.deleteOrderItem(con, id);
            oDao.deleteOrder(con, id);
            con.commit();
        } catch (SQLException e) {
            e.printStackTrace();
            if(con!=null)
                try {
                    con.rollback();
                } catch (SQLException e1) {
                    e1.printStackTrace();
                }
        }
    }
}

10.3 订单控制层及其界面

10.3.1 订单提交控制层及其界面

OrderSubmitServlet.java

package cn.ghw.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/order_submit")
public class OrderSubmitServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        if(request.getSession().getAttribute("user")!=null) {
            request.getRequestDispatcher("/order_submit.jsp").forward(request, response);
        }else {
            request.setAttribute("failMsg", "请登录后,再提交订单!");
            request.getRequestDispatcher("/user_login.jsp").forward(request, response);
        }
    }
}

order_submit.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
    <title>支付</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/bootstrap.css">
    <link rel="stylesheet" href="css/style.css">
    <script src="js/jquery.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script src="layer/layer.js"></script>
    <script src="js/cart.js"></script>
</head>
<body>

    <!--header-->
    <jsp:include page="/header.jsp"/>
    <!--//header-->

    <div class="cart-items">
        <div class="container">
            <h2>确认收货信息</h2>
            <form class="form-horizontal" action="order_confirm" method="post" id="payform">
                <div class="row">
                    <label class="control-label col-md-1">收货人</label>
                    <div class="col-md-6">
                        <input type="text" class="form-control" name="收货人名称" value="${user.名称 }" style="height:auto;padding:10px;" placeholder="输入收货人" required="required"><br>
                    </div>
                </div>name
                <div class="row">
                    <label class="control-label col-md-1">收货电话</label>
                    <div class="col-md-6">
                        <input type="text" class="form-control" name="收货电话" value="${user.电话 }" style="height:auto;padding:10px;" placeholder="输入收货电话" required="required"><br>
                    </div>
                </div>
                <div class="row">
                    <label class="control-label col-md-1">收货地址</label>
                    <div class="col-md-6">
                        <input type="text" class="form-control" name="收货地址" value="${user.地址 }" style="height:auto;padding:10px;" placeholder="输入收货地址" required="required"><br>
                    </div>
                </div>
                <br><hr><br>

                <h2>选择支付方式</h2>
                <h3>支付金额: ${order.总额 }</h3><br><br>


                <div class="col-sm-6 col-md-4 col-lg-3 " >
                    <label>
                        <div class="thumbnail">
                            <input type="radio" name="支付方式" value="1" checked="checked" />
                            <img src="images/wechat.jpg" alt="微信支付">
                        </div>
                    </label>
                </div>
                <div class="col-sm-6 col-md-4 col-lg-3 " >
                    <label>
                        <div class="thumbnail">
                            <input type="radio" name="支付方式" value="2"  />
                            <img src="images/alipay.jpg" alt="支付宝支付">
                        </div>
                    </label>
                </div>
                <div class="col-sm-6 col-md-4 col-lg-3 ">
                    <label>
                        <div class="thumbnail">
                            <input type="radio" name="支付方式" value="3"  />
                            <img src="images/offline.jpg" alt="货到付款">
                        </div>
                    </label>
                </div>
                <div class="clearfix"> </div>
                <div class="register-but text-center">
                    <input type="submit" value="确认订单">
                    <div class="clearfix"> </div>
                </div>
            </form>
        </div>
    </div>

    <!--footer-->
    <jsp:include page="footer.jsp"/>
    <!--//footer-->

    <script>
        function dopay(paytype){
            $("#paytype").val(paytype);
            $("#payform").submit();
        }
    </script>

</body>
</html>
图22 提交订单界面【确认订单】

10.3.2 订单确认控制层及其界面

OrderConfirmServlet.java

package cn.ghw.servlet;

import cn.ghw.model.Order;
import cn.ghw.model.User;
import org.apache.commons.beanutils.BeanUtils;
import cn.ghw.service.OrderService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;

@WebServlet("/order_confirm")
public class OrderConfirmServlet extends HttpServlet {
    private OrderService oService = new OrderService();
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Order o = (Order) request.getSession().getAttribute("order");
        try {
            BeanUtils.copyProperties(o, request.getParameterMap());
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        o.set下单时间(new Date());
        o.set订单状态(2);
        o.setUser((User) request.getSession().getAttribute("user"));
        oService.addOrder(o);
        request.getSession().removeAttribute("order");

        request.setAttribute("msg", "订单支付成功!");
        request.getRequestDispatcher("/order_success.jsp").forward(request, response);
    }
}

order_success.jsp 支付成功 < a href="order_list">查看我的订单</ a>

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>
<html>
<head>
    <title>支付成功</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/bootstrap.css">
    <link rel="stylesheet" href="css/style.css">
    <script src="js/jquery.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script src="layer/layer.js"></script>
    <script src="js/cart.js"></script>
</head>
<body>
    <!--header-->
    <jsp:include page="header.jsp"/>
    <!--//header-->

    <!--cart-items-->
    <div class="cart-items">
        <div class="container">
            <c:if test="${!empty msg }">
                <div class="alert alert-success">${msg }</div>
            </c:if>
            <p><a class="btn btn-success" href="order_list">查看我的订单</a></p>
        </div>
    </div>
    <!--//cart-items-->

    <!--footer-->
    <jsp:include page="footer.jsp"/>
    <!--//footer-->

</body>
</html>
图23 确认订单界面

10.3.3 订单列表控制层及其界面

OrderListServlet.java

package cn.ghw.servlet;

import cn.ghw.model.Order;
import cn.ghw.model.User;
import cn.ghw.service.OrderService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

@WebServlet("/order_list")
public class OrderListServlet extends HttpServlet {
    private OrderService oService = new OrderService();

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        User u = (User) request.getSession().getAttribute("user");
        if(u==null) {
            response.sendRedirect("/index");
            return;
        }
        List<Order> list = oService.selectAll(u.getId());
        request.setAttribute("orderList", list);
        request.getRequestDispatcher("/order_list.jsp").forward(request, response);
    }
}

order_list.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>
<html>
<head>
    <title>我的订单</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/bootstrap.css">
    <link rel="stylesheet" href="css/style.css">
    <script src="js/jquery.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script src="layer/layer.js"></script>
    <script src="js/cart.js"></script>
</head>
<body>
    <!--header-->
    <jsp:include page="header.jsp">
        <jsp:param name="flag" value="5"/>
    </jsp:include>
    <!--//header-->

    <!--cart-items-->
    <div class="cart-items">
        <div class="container">

            <h2>我的订单</h2>

                <table class="table table-bordered table-hover">

                <tr>
                    <th width="10%">ID</th>
                    <th width="10%">总价</th>
                    <th width="20%">商品详情</th>
                    <th width="30%">收货信息</th>
                    <th width="10%">订单状态</th>
                    <th width="10%">支付方式</th>
                    <th width="10%">下单时间</th>
                </tr>

                    <c:forEach items="${orderList }" var="order">

                        <tr>
                            <td><p>${order.id }</p></td>
                            <td><p>${order.总额 }</p></td>
                            <td>
                                <c:forEach items="${order.itemList }" var="item">
                                    <p>${item.商品名称 }(${item.单价 }) x ${item.数量 }</p>
                                </c:forEach>

                            </td>
                            <td>
                                <p>${order.收货人名称 }</p>
                                <p>${order.收货电话 }</p>
                                <p>${order.收货地址 }</p>
                            </td>
                            <td>
                                <p>
                                    <c:if test="${order.订单状态==1 }"><span style="color:red;">未付款</span></c:if>
                                    <c:if test="${order.订单状态==2 }"><span style="color:red;">已付款</span></c:if>
                                    <c:if test="${order.订单状态==3 }"><span style="color:green;">已发货</span></c:if>
                                    <c:if test="${order.订单状态==4 }"><span style="color:black;">已完成</span></c:if>
                                </p>
                            </td>
                            <td>
                                <p>
                                    <c:if test="${order.支付方式==1 }">微信</c:if>
                                    <c:if test="${order.支付方式==2 }">支付宝</c:if>
                                    <c:if test="${order.支付方式==3 }">货到付款</c:if>
                                </p>
                            </td>
                            <td><p>${order.下单时间 }</p></td>
                        </tr>
                    </c:forEach>

                </table>

        </div>
    </div>
    <!--//cart-items-->

    <!--footer-->
    <jsp:include page="footer.jsp"/>
    <!--//footer-->

</body>
</html>
图24 我的订单界面
图25 前端开发--程序构成

返回