项目总结
项目源码:https://download.csdn.net/download/zitian246/12920193
数据库文件与页面梳理:https://download.csdn.net/download/zitian246/12920210
1.项目开发流程
需求分析:确认客户最终需求
概要设计: 考虑系统的基本组织流程,组织结构、模块划分、接口设计等
详细设计: 在上一步基础上,考虑模块设计的算法、数据结构,类之间的调用关系等
编码、测试、交付、验收、维护
2.开发环境与主要功能
开发环境: 无框架
- 数据库 Mysql 5.7+
- 服务器 tomcat8.5
- 集成环境 idea
序号 | 模块名称 | 主要功能 |
---|---|---|
1 | 商品显示模块 | 分页显示所有商品查看单个商品详细信息搜索商品 |
2 | 用户模块 | 新用户注册用户登录用户退出 |
3 | 购物车模块 | 加入商品到购物车修改所购商品数量 |
4 | 订单模块 | 提交订单并显示订单信息用户确认后生成正式订单用户查看历史订单 |
5 | 支付模块 | 完成在线支付功能 |
6 | 收货地址 | 管理收货地址 |
7 | 后台模块 | 主要实现商品的增删改查 |
3.数据库设计
建表原则:现实生活中,实体与实体之间肯定有关系,那么在设计表时,就需要体现这种关系。常见的有三种。
一对多:
(1:n):例如:1.订单(order)与订单条目(item) 2.用户(user)与购物车(cart) 3.用户(user)与地址(address) 4.用户(user)与订单(order) 5.类型(type)与商品(product)等
原则:在从表(多方n)创建一个字段,字段作为外键指向主表(一方)的主键id
多对多:
(m:n):例如: 订单(order)与商品(product)
原则:需要创建第三张表,中间表至少两个字段,这两个字段分别作为外键指向各自一方的主键
一对一:例如用户表
在实际的开发中应用不多.因为一对一的表可以创建成一张表。
4.创建项目框架
导入baseServlet工具包
导入jar包
5.登录模块
登录流程:
1.验证验证码
2.验证用户是否激活
3.验证用户名密码 数据库中的密码是加密后
技术难点:
1.鉴权登录(session,filter):登录验证成功,存入session。
访问其他需要登录的资源(logined)时,如果在LoginFilter获取session的属性,如果存在此用户,不做任
何处理,即(filterChain)放行,否则重定向到登录页。
2.自动登录(cookie):如果用户勾选自动登录,创建一个cookie,存入编码后的用户名密码,设置生命周期,通过响应头通知浏览器写入。再次登录时,比对cookie与数据库密码信息
String autoUser = Base64Utils.encode(user.getUsername() + Constants.FLAG + user.getUpassword()); Cookie cookie = new Cookie(Constants.AUTO_NAME,autoUser);
注销登录:
创建cookie,,设置存活时间为0,覆盖原来的。通知浏览器使其失效
6.注册模块
流程:
- 判断用户名是否可用:通过Ajax异步请求,局部刷新页面
- 登录邮箱激活,将随机生成的激活码绑定到url上,用户点击,即激活。
7.商品显示模块
7.1分页显示商品列表(难点)
分页三个重要元素:当前页(currentPage),总页数(totalPage),每页显示的最大数量(pageSize)。
拥有这三个信息,即可达成分页。
实现步骤:
1.创建一个实体类PageBean。用于封装获取的数据。字段如下:
- List list :封装数据
- pageSize 每页显示的最大数量
- totalPage 总页数
- totalCount 数据总条数 用于计算总页数
- currentPage 当前页
2.数据准备:
查询数据总条数: String sql = "select count(1) from product where t_id = ?
计算总页数:
// 计算总页数 if (totalCount%pageSize==0){ totalPage = (int)totalCount/pageSize; }else { totalPage = (int)totalCount/pageSize + 1; }
pageSize与currentPage均设置默认值
3.查询数据 limit (pageIndex-1)*pageSize,pageSize;封装到pageBean中
7.2商品详情页
product表数据。存储到request的作用域后,转发到jsp 展示
7.3商品模糊查询(重要)并分页
1.servlet改进: 绑定上搜索的文本内容拼接url。
2.sql查询
根据关键字查询分页集合数据,并封装
查找符合关键字的商品数量,计算总页数
public PageBean<Product> searchProductByUser(String name, int pageIndex, int PageSize) throws SQLException { // 1.根据关键字查询分页集合数据 List<Product> productList = productDao.getProductByCondition(name, pageIndex, PageSize); //2.查找符合关键字的商品数量,计算总页数 int totalCount = productDao.getProductCountByCondition(name); //totalCount数据总条数,总页数在构造函数中计算了 return new PageBean<Product>(productList,pageIndex,PageSize,totalCount); }
3.sql查询语句
7.4模糊查询参数数量报错问题(重要)
原因:模糊查询进行了转义 %‘字段’% 的值加上了 ‘’ 导致查询报错
解决办法:String newUsername ="%"+username+"%"; 将要传入的参数直接加上%%,作为一个整体参数传入
@Override
public List<User> getUserByCondition(String username, String gendar) throws SQLException {
String sql = "select u_id as uid , u_name as username , u_password as upassword, u_sex as usex , " +
"u_status as ustatus , u_code as code , u_email as email, u_role as urole from user ";
if(StringUtils.isEmpty(gendar) && !StringUtils.isEmpty(username)){
sql += " where u_name like ?";
String newUsername = "%" + username + "%";
return queryRunner.query(sql,new BeanListHandler<>(User.class),newUsername);
}else if(!StringUtils.isEmpty(gendar) && StringUtils.isEmpty(username)){
sql += " where u_sex = ?";
return queryRunner.query(sql,new BeanListHandler<>(User.class),gendar);
}else if(!StringUtils.isEmpty(gendar) && !StringUtils.isEmpty(username)){
sql += " where u_name like ? and u_sex = ?";
String newUsername = "%" + username + "%";
System.out.println(sql);
System.out.println(sql);
return queryRunner.query(sql,new BeanListHandler<>(User.class),newUsername,gendar);
}else{
return queryRunner.query(sql,new BeanListHandler<>(User.class));
}
8.购物车模块
1.加入购物车:
- 根据用户uid与商品pid判断用户是否加入过此商品
- 有则加购,无则添加此商品,并设置数量为1.
2.购物车展示:
- 涉及两表数据:cart,product
- 实体类 cart里有Product product 字段,直接联表查询封装即可
9.订单模块
9.1订单预览
设计到的表: orders address
实体类: Orders :内部有Address属性
9.2生成订单功能
订单号的生成:下单时间+随机数保证唯一
订单状态:0未付款,1已经付款未发货 2发货待收货 3 收货待评价 4订单完成
订单生成的步骤:
- 在order中增加一条数据
- 并且将购物车中的商品添加到item中,order与item是一对多的关系,item中有外键指向order的主键
- 清空购物车,把此项购物车数据删除
9.3订单详情页
涉及到的表:product,address,order,item
涉及到的实体类:orders 内部有Address,List items属性,联表查询转发到jsp页面展示
10.支付模块
调用支付宝接口。
在沙盒环境下进行测试。
提供的数据:订单号,订单金额,订单说明(介绍)
根据回调函数判断是否支付成功,进行订单状态的修改
11.后台管理模块
11.1用户管理与模糊查询
设计到的表:user
模糊查询与商品搜索实现类似。注意sql语句模糊查询参数数量报错问题。此时并非sql写错。
11.2商品展示与模糊查询
涉及到的表: product,直接查询即可
商品类型:type
11.3商品添加与图片的上传(难点)
涉及到的表product
图片、音频等文件上传与写明enctype=“multipart/form-data”,表示以二进制形式传输
此时纯文本内容如名称、商品介绍也会以二进制形式传输,通过req.getParameter()无法获取参数(getParameter()是通过键值对获取的,此时只有二进制信息,无键值对)
解决方案:https://www.cnblogs.com/jimisun/p/9419269.html
- 设计到的jar包commons-fileupload-1.3.1.jar与commons-io-2.8.0.jar
11.4订单状态与模糊查询
涉及到的表:orders,直接查询
模糊查询:注意条件为空的情况
12.项目中难点分析
1.鉴权登录,通过**session 与过滤器(Filter)**实现
2.自动登录,通过在浏览器存储含有用户信息的cookie,并设置存活时间,实现,通过filter拦截实现自动登录
3.模糊查询:sq模糊查询进行了转义 %‘字段’% 的值加上了 ‘’ 导致sql语句查询报错。需拼接字符串作为新的参数传入
4.添加购物车:添加前需要判断当前用户是否添加过此商品
5.生成订单:生成订单的流程容易忽视,会只创建插入order数据,比如忘记商品信息插入item中,删除cart表信息
6.form表单中图片与文本内容同时上传,.getParameter()无法获取参数
13.项目中遇到的问题或bug
1.空指针异常:这是出现最多的异常,比如忽视了查询数据为空的情况,直接使用。再如:管理员与用户登录使用了同一个login方法登录,而管理员界面是没有验证码的
2.Wrong number of parameters:模糊查询时sql参数个数异常。如sql语句写为where u_name like ‘%?%’。需拼接字符串解决
3.ClassNotFoundException:这是很明显的异常,使用工具上传图片时忘记导入了需要的jar包
14.前端界面和后台数据的交互方式
1.通过servlet获取数据,将其存储到request、session等作用域中,然后转发到jsp展示。
2.通过添加ajax异步请求事件从sevlet获取数据,局部刷新界面。