项目搭建
1.前台需求分析
前台是针对用户购书,而后台是管理员管理系统。
1.1前台主页
/index.jsp使用<jsp:forward>转发到/jsps/main.jsp,、main.jsp中只有一个<table>,结构如下
(1)图书商城 用户名:张三 我的购物车 我的订单 修改密码 退出 |
|
(2)图书分类 |
(3)搜索图书 |
(4)轮播图
|
<table>中各个部分使用的是<iframe>完成的框架页。
(1):/jsps/top.jsp;
(2):/jsps/left.jsp;
(3):/jsps/search.jsp;
(4):/jsps/body.jsp
在(1)、(2)、(3)部分都存在超链接或表单,无论点击哪个超链接(或提交表单)都会在(4)部分显示。
1.2 模块划分
系统分为如下模块:
- 用户模块
- 分类模块
- 图书模块
- 购物车模块
- 订单模块
1.3 前台用户模块
用户模块功能有:
- 注册
- 登录
- 修改密码
- 退出
1.4 前台分类模块
分类模块功能有:
- 显示一级所有分类;
- 显示二级所以分类
1.5 前台图书模块
前台图书模块功能有:
- 查看指定分类的图书;
- 查看指定名称的图书;
- 查看指定条件的图书;
- 查看图书详细信息。
1.6 购物车模块
购物车模块功能有:
- 向购物车中添加条目;
- 查看我的购物车;
- 修改条目数量;
- 删除条目;
- 批量删除条目;
1.7 前台订单模块
前台订单模块功能有:
- 生成订单;
- 查看我的订单;
- 查看订单详细信息;
- 取消订单;
- 确认收货;
- 支付订单;
2.后台需求分析
后台是管理员管理系统,以售书功能。
2.1 后台主页
(1)后台管理 管理员:张三 退出 分类管理 图书管理 订单管理 |
(2)轮播图
|
与前台主页一样,使用框架页。
2.2 管理员模块
管理员模块功能有:
- 管理员登录;
- 管理员退出;
2.3 后台分类管理
后台分类管理功能有:
- 查看所有分类;
- 添加一级分类;
- 添加二级分类;
- 编辑一级分类;
- 编辑二级分类;
- 删除一级分类;
- 删除二级分类;
2.4 后台图书管理
后台图书管理功能有:
- 查看指定分类的图书;
- 查看指定条件的图书;
- 添加新图书;
- 编辑图书;
- 删除图书;
2.5 后台订单管理
后台订单管理功能有:
- 查看所有订单;
- 查看订单详细信息;
- 订单发货;
- 取消订单;
3. 数据模型设计
- User:用户;
- Category:图书分类;
- Book:图书;
- CartItem:购物车条目;
- Order:订单;
- OrderItem:订单条目;
- Admin:管理员。
t_user表
字段名 |
数据类型 |
约束条件 |
长度 |
是否可空 |
注释 |
id |
int |
主键 |
11 |
否 |
用户ID |
name |
varchar |
|
50 |
否 |
用户名 |
pwd |
varchar |
|
50 |
否 |
密码 |
|
varchar |
|
50 |
否 |
邮箱 |
t_category表
字段名 |
数据类型 |
约束条件 |
长度 |
是否可空 |
注释 |
cid |
char |
主键 |
32 |
否 |
分类ID |
Cname |
varchar |
|
50 |
|
分类名 |
parent |
varchar |
|
50 |
|
一级分类名 |
children |
varchar |
|
50 |
|
二级分类名 |
desc |
vaechar |
|
100 |
|
分类描述 |
t_book表
字段名 |
数据类型 |
约束条件 |
长度 |
是否可空 |
注释 |
bid |
char |
主键 |
32 |
否 |
图书ID |
bname |
varchar |
|
200 |
|
书名 |
author |
varchar |
|
50 |
|
作者 |
price |
decimal |
|
8 |
|
定价 |
currprice |
decimal |
|
8 |
|
当前价 |
discount |
decimal |
|
3 |
|
折扣 |
press |
varchar |
|
100 |
|
出版社 |
publishtime |
char |
|
10 |
|
出版时间 |
edition |
int |
|
11 |
|
版次 |
pagenum |
int |
|
11 |
|
页数 |
wordnum |
int |
|
11 |
|
字数 |
printtime |
char |
|
10 |
|
印刷时间 |
booksize |
int |
|
11 |
|
开本 |
paper |
varchar |
|
50 |
|
纸张 |
number |
int |
|
4 |
|
数量 |
cid |
varchar |
|
32 |
|
类别 |
image_w |
varchar |
|
100 |
|
大图 |
Image_b |
varchar |
|
100 |
|
小图 |
t_cartitem表
字段名 |
数据类型 |
约束条件 |
长度 |
是否可空 |
注释 |
cartitemid |
char |
主键 |
32 |
否 |
购物车ID |
quantiy |
int |
|
10 |
|
数量 |
bid |
char |
|
32 |
|
图书ID |
uid |
char |
|
32 |
|
用户ID |
t_order表
字段名 |
数据类型 |
约束条件 |
长度 |
是否可空 |
注释 |
oid |
char |
主键 |
32 |
否 |
订单ID |
ordertime |
char |
|
20 |
|
订单时间 |
total |
decimal |
|
10 |
|
总计 |
status |
int |
|
11 |
|
订单状态 |
adress |
varchar |
|
1000 |
|
收货地址 |
user |
char |
|
32 |
|
订单用户 |
t_orderitem表
字段名 |
数据类型 |
约束条件 |
长度 |
是否可空 |
注释 |
Orderitemid |
char |
主键 |
32 |
否 |
订单条目ID |
quantiy |
int |
|
11 |
|
数量 |
subtotal |
decimal |
|
8 |
|
总计 |
bid |
char |
|
32 |
|
图书ID |
bname |
varchar |
|
200 |
|
书名 |
currprice |
decimal |
|
8 |
|
当前价 |
Image_b |
varchar |
|
100 |
|
小图 |
oid |
char |
|
32 |
|
订单ID |
t_admin表
字段名 |
数据类型 |
约束条件 |
长度 |
是否可空 |
注释 |
adminid |
int |
主键 |
10 |
否 |
管理员ID |
adminname |
varchar |
|
50 |
|
管理员名 |
adminpwd |
varchar |
|
50 |
|
密码 |
4. 项目框架
4.1 导包
项目所需要导什么包,要从项目所使用的工具来计算。本项目需要使用工具如下:
- c3p0;
- commons-beanutils;
- commons-dbutils;
- commons-fileupload;
- commons-fileupload.jar;
- javamail;
- Log4J;
- mysql-connector;
- itcast-tools。
4.2 配置文件
本项目使用了C3P0数据库连接池,所以需要在src下配置c3p0-config.xml文件。模板如下:
c3p0-config.xml
<?xml version="1.0" encoding="UTF-8" ?> <c3p0-config> <default-config> <property name="jdbcUrl">jdbc:mysql://localhost:3306/goods</property> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="user">root</property> <property name="password">123</property>
<property name="acquireIncrement">3</property> <property name="initialPoolSize">10</property> <property name="minPoolSize">2</property> <property name="maxPoolSize">10</property> </default-config> </c3p0-config> |
4.3 JQuery异步请求
本项目的页面中使用JQuery来完成表单的校验,而且还使用了JQuery的AJAX。这里简单回顾一下使用JQuery发送异步请求的过程。
使用JQuery发送异步请求最为灵活的方法是ajax()方法,该方法只有一个参数,参数为一个JSON对象,下面来看看这个对象的属性。
- async:默认为true,表示发送异步请求。
- beforeSend:函数类型。该函数会在发送请求前被调用,可以用来设置自定义的HTTP报头。该函数有一个参数为XMLHttpRequest类型,我们可以使用它完成底层AJAX的设置,如果该函数返回false,那么当前请求会被取消。
- cache:默认为true,表示是否在浏览器缓存中加载信息。当dataType为script时,该属性为false。
- complete:函数类型,无论请求是否成功,当请求结束时调用它。该函数有两个参数,function (XMLHttpRequest, textStatus)。
- contentType:默认为application/x-www-form-urlencoded,一般无需修改该属性。
- data:请求参数,格式为{key1:val1,key2:val2…}。如果val为数组那么会被转换为多个参数,例如{key:[val1,val2]}转换为key=val1&key=val2。
- dataType:可选值为xml、html、script、json、jsonp、text。表示服务器的响应数据的类型。
- type:默认为GET,表示请求方式。POST和GET使用的比较多。
- url:请求的服务器资源,可以是一个html、xml、jsp和Servlet等。
- success:请求成功调用的函数。函数形如fun(data,status),其中data为通过dataType进行了转换的服务器响应数据。
- error:请求失败时调用的函数。函数形如fun(XMLHttpRequest, status, errorThrown) 。
常用属性有6个:
- url:要请求的服务器端地址
- dataType:服务器返回数据的类型,我们通常用json;
- data:客户端发送给服务器的参数;
- type:请求方法,可以是GET或POST
- async:是否为异步(如果为true,那么是用两个线程来完成,否则是一个线程)
- cache:客户端是否缓存数据。
- success:成功是调用的方法。
例如:
<script type="text/javascript" src="<c:url value='/js/jquery-1.5.1.js'/>"></script> <script type="text/javascript"> $(function() { $("#btn").click(function() { var name = $("#name").val(); if(name) { $.ajax({ async: false, cache: false, type: "POST", dataType: "json", url: "<c:url value='/AjaxServlet'/>", data: {method: "findByName", name: name}, success: function(person) { $("#person").text(person.pid + ", " + person.name + ", " + person.age + ", " + person.birthday); } }); } }); }); </script> |
<body> 请输入姓名:<input type="text" id="name" name="name"/> <input type="submit" value="查询" id="btn"/> <div id="person"></div> </body> |
public class AjaxServlet extends BaseServlet { public String findByName(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = request.getParameter("name"); PersonDao dao = new PersonDao(); try { Person person = dao.findByName(name); StringBuilder sb = new StringBuilder(); sb.append("{"); sb.append("\"pid\":").append("\"").append(person.getPid()).append("\","); sb.append("\"name\":").append("\"").append(person.getName()).append("\","); sb.append("\"age\":").append("\"").append(person.getAge()).append("\","); sb.append("\"birthday\":").append("\"").append(person.getBirthday()).append("\""); sb.append("}"); response.getWriter().print(sb); } catch (SQLException e) { throw new RuntimeException(e); } return null; } } |
5. 添加过滤器
添加编码过滤器
web.xml
<filter> <filter-name>EncdoingFilter</filter-name> <filter-class>cn.itcast.filter.EncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>EncdoingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> |