本购物系统需要实现商品信息的显示、基本的购物流程、商品的管理等基础功能。下图表示具体的功能及各功能之间的联系:
购物商城系统的ER模型描述如下图所示:
此模块的主要目的为实现用户的账号注册与账号登陆功能。
注册
通过获取用户输入的信息,向后端发送<用户名,密码,确认密码,邮箱>表单,并调用后端productServlet中的 register方法,在register方法中,首先将前端传来的表单存储到User类的实例化对象usr中;
再判断两次密码输入的是否一致,如果不一致则返回失败信息,如果一致则调用类ProductService实例化对象中的register接口,该接口的主要功能是连接数据库,将usr中的信息与数据库表单对比,如果存在主键相同的情况则返回错误信息,如果不存在则将usr中的信息存入数据库表单,并返回成功信息;最后,通过重定向到登陆页面,完成注册操作
人脸识别登录
在前端jsp页面中通过调用摄像头获取用户照片;
使用post方法将图片和用户信息上传至后端服务器
后端接收到图片后通过获取的用户信息读取表单,查询用户预存人脸图片;
通过调用facereg类的match函数对比上传的图片与预存图片的人脸相似度,并返回判断结果,该函数主要通过使用百度的人脸识别api,通过百度分配的api Key进行认证,上传识别图片,获取返回的json类型结果,对结果进行分析就能得到识别结果。
验证码:
为了保证用户登录的安全,在登录时用户需要输入验证码。验证码如下图:
后台验证码文本文档:
后台首先读入验证码文本文档并随机选取一行文字,之后使用了Graphics对象,在内存中创建出一张包含选取文字的验证码图片,并绘制干扰线。当前端请求该方法时,将生成的图片传到前端界面显示,同时将验证码答案放到session中,当用户登陆时,如果验证码不对则返回”验证码错误“且无法登陆。
核心功能代码:
// 步骤一 绘制一张内存中图片
BufferedImage bufferedImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
// 步骤二 图片绘制背景颜色 ---通过绘图对象
Graphics graphics = bufferedImage.getGraphics();// 得到画图对象 --- 画笔
// 绘制任何图形之前 都必须指定一个颜色
graphics.setColor(getRandColor(200, 250));
graphics.fillRect(0, 0, width, height);
// 步骤三 绘制边框
graphics.setColor(Color.WHITE);
graphics.drawRect(0, 0, width - 1, height - 1);
此模块的主要目的为实现商品的搜索功能。
语音搜索
单击搜索框右侧的该按钮进行录音,设置音频采集格式;
以FormData的格式上传到后端服务器,通过FilePost类中的doPost方法接收音频文件并保存,再调用audioTest类中的running方法;
running方法主要通过百度的语音识别api,上传一段采样位数16位采样率16000的pcm音频文件,通过解析返回的json数据可以得到识别的内容;
获得结果;
将识别结果返回给前端并显示;
点击搜索即可获得搜索结果;
商品显示
①商品类别显示:
所有商品信息都存储在数据库,为了显示对应的商品首先需要显示数据库中的所有的商品类别,再点击商品类别前端将商品类别id传给后端,后端将数据库中的数据显示出来。
后端核心代码:
public void cateProductList(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String cid = req.getParameter("cid");
List
try {
list = service.cateProductList(cid);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
req.setAttribute("cid", cid);
req.setAttribute("list", list);
req.getRequestDispatcher("/list.jsp").forward(req, resp);
}
商品类别显示:
选择类别手机:
显示了所有手机信息。
②商品详细信息显示
点击某一商品后,前端将所请求的商品id传给后端,后端通过重定向将商品详细信息显示到list.jsp中。
后端核心代码:
public void productInfo(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException, SQLException {
String cid = req.getParameter("cid");
String pid = req.getParameter("pid");
Product product = service.findProductById(pid);
req.setAttribute("product", product);
req.getRequestDispatcher("/product_info.jsp").forward(req, resp);
}
详情页显示:
信息录入
4.1.4.1修改密码
为了方便用户修改自己账号的密码,此网上商城系统设计了修改密码功能。已登录用户在修改密码时,在网上商城系统前端界面中输入自己的原密码以及修改的新密码,还设计了需要用户再次输入新密码,使用Javascript脚本对两次输入的新密码进行比对,确保用户输入的两次新密码是相同的,没有发生因打字错误出现密码输入不正确的问题,然后前端通过表单将前端输入的信息传入后端servlet程序中,程序中通过request的getParament方法获取到用户的用户名、旧密码、新密码三个信息,然后通过Connection conn = DBHelper.getConnection()语句与数据库建立连接,建立连接成功后,创建一个Statement的对象,用此对象的execute方法执行Mysql的update语句将用户需要修改的新密码更新到数据库中,前后端代码编码完成之后,需要在web.xml配置文件中编写配置标签,以便前端与后端在实际运行过程中能够连接在一起。
4.1.4.2人脸录入
此网上商城系统中设计了人脸识别登录功能,要想完成人脸识别登录,必须先在系统中录入要登录的用户的脸部照片。首先在前端页面代码中编写Javascript在网页中调用计算机的摄像头进行拍照,拍完照之后通过ajax技术将照片提交到后端,在后端代码编写的servlet代码中需要进行两部分操作:将照片保存到本地和将照片的本地地址保存到数据库中,同时前端还需要将要进行人脸录入的用户的用户名提交到后端,以此来保证用户录入的照片与用户名进行绑定。在后端代码中通过request.getParameter语句获取到用户的用户名,然后通过fileName = (new Date()).getTime()+".png"语句确定用户照片的文件名,用时间来对用户照片进行标记,以此来保证照片的文件名不会重复。通过filePath = request.getSession().getServletContext().getRealPath("/") + basePath语句确定用户照片所存储的本地磁盘的路径位置。图片在前后端传输过程中以字节流形式存在,通过request.getParameter获取到字节流,然后通过GenerateImage函数完成将字节流转换为图片并保存到本地磁盘中,此函数的具体实现如下:
public boolean GenerateImage(String imgStr, String filePath, String fileName) {
try {
if (imgStr == null) {
return false;
}
BASE64Decoder decoder = new BASE64Decoder();
//Base64解码
byte[] b = decoder.decodeBuffer(imgStr);
//如果目录不存在,则创建
File file = new File(filePath);
if (!file.exists()) {
file.mkdirs();
}
//生成图片
OutputStream out = new FileOutputStream(filePath + fileName);
out.write(b);
out.flush();
out.close();
return true;
} catch (Exception e) {
return false;
}
}
由于此系统在设计人脸识别登录功能时已唯一确定保存图片的目录,因此只要将图片的文件名保存到数据库中就可以唯一确定图片,要将图片的文件名插入到数据库的指定用户名的那一行,此插入通过执行Mysql的update语句来实现。
完成效果:
4.1.5购物车设计
4.1.5.1加入购物车功能
在网上商城系统中需要有加入购物车功能,在物品详细信息界面中,点击button加入购物车,通过cookie将所选的物品的信息进行保存,保存方式为本地存储,然后传输到购物车界面并在购物车界面中对商品信息进行显示。
完成效果:
地址管理功能
收货地址界面
商品付款功能
在确定商品订单之后要对商品进行付款,要实现付款功能,需要前端将付款订单的id传入到后端中,后端通过request.getParament方法获取到订单id,然后将一些必要的信息发送给第三方支付平台,具体信息定义如下:
String p0_Cmd = "Buy";
String p1_MerId = ResourceBundle.getBundle("merchantInfo").getString("p1_MerId");
String p2_Order = orderid;
String p3_Amt = money;
String p4_Cur = "CNY";
String p5_Pid = "";
String p6_Pcat = "";
String p7_Pdesc = "";
并且要对这些发送到第三发支付平台的信息进行加密,具体的加密语句如下:String keyValue = ResourceBundle.getBundle("merchantInfo").getString("keyValue");
String hmac = PaymentUtil.buildHmac(p0_Cmd, p1_MerId, p2_Order, p3_Amt,p4_Cur, p5_Pid, p6_Pcat, p7_Pdesc, p8_Url, p9_SAF, pa_MP,pd_FrpId, pr_NeedResponse, keyValue);
加密完成之后通过重定向的方式跳转到第三方支付平台,待支付完成之后,第三方支付平台会重新跳转到网上商城的界面中放回支付结果信息,前端获取后对支付结果进行显示。
完成效果:
我的订单设计
在网上商城系统中,需要设计我的订单功能。在用户在前端界面中查询我的订单时会在前端界面中显示用户的订单信息。订单的信息都被保存在数据库orders和orderitem两个表中,orders中保存了订单id、物品数量、是否付款、订单地址、用户姓名、用户电话、用户id,在orderitem表中保存了物品的数量、物品的总价格、产品id和订单id,在对订单进行查询的过程中,需要对user、orders、orderitem三个表经行连接查询才能得到订单的信息。前端通过session将已登录用户的用户名传到后端,后端通过request的getParament方法获取到用户的用户名,然后通过Mysql的select语句由用户名找到用户id,再由用户id在orders表和orderitem表中找到与此用户id相关联的所有订单信息,将订单信息通过json传到前端,前端解析json获取到所有的订单信息并通过控件将订单信息在前端界面中进行显示。
完成效果:
在网上商城系统中,需要设计商品收藏的功能,以便用户能够对喜欢的商品进行收藏,并且以后再次进入网上商城之后能够快捷地找到商品。在加入购物车界面之后会显示收藏地选项,对商品进行收藏显示功能主要通过session来完成。前端通过session将商品名称、商品价格、商品的显示图片、商品数量和商品的总价格以及已登录用户的用户名这些信息传到后端,后端在session中获取。然后当转到我的收藏的界面中时,前端从session中获取到此前传入的信息,并在前端界面中使用控件对收藏的商品信息进行显示。
完成效果:
后台管理页面具体实现
前端界面样式使用了JQueryUI库,通过Ajax请求和后端进行数据交互。后端通过查询数据库,将数据库信息以JasonArray的形式传给前端。
后端显示商品核心代码:
List
Gson gson=new Gson();
resp.getWriter().write(gson.toJson(list));
前端显示数据到表格:
<table class="easyui-datagrid" id="itemList" title="商品列表" data-options="singleSelect:false,collapsible:true,pagination:true,url:'${pageContext.request.contextPath }/adminproduct?method=adminProductList',method:'post',pageSize:30,toolbar:toolbar">
新增商品:管理员输入对应的商品信息之后即可显示新增的商品。
查询商品:点击查询商品按钮即可显示数据库中的所有商品:
刚刚新加的商品也已经显示出来了。
用户信息表
字段名 |
描述 |
类型 |
长度 |
空 |
是否主键 |
uid |
用户唯一标识 |
varchar |
50 |
否 |
是 |
username |
用户名 |
varchar |
20 |
否 |
否 |
password |
用户密码 |
varchar |
10 |
否 |
否 |
name |
用户姓名 |
varchar |
10 |
否 |
否 |
sex |
用户性别 |
varchar |
10 |
否 |
否 |
|
用户邮箱 |
varchar |
255 |
否 |
否 |
picture |
用户人脸图片地址 |
varchar |
255 |
否 |
否 |
商品信息表
字段名 |
描述 |
类型 |
长度 |
空 |
是否主键 |
pid |
商品唯一标识 |
varchar |
50 |
否 |
是 |
pname |
商品名 |
varchar |
255 |
否 |
否 |
pimage |
商品图片路径 |
varchar |
255 |
否 |
否 |
price |
价格 |
double |
0 |
否 |
否 |
succ_count |
商品售出数量 |
int |
11 |
否 |
否 |
pdesc |
商品描述 |
mediumtext |
0 |
否 |
否 |
is_hot |
是否热门 |
int |
11 |
否 |
否 |
pdate |
商品录入日期 |
date |
0 |
否 |
否 |
cid |
商品类别 |
varchar |
50 |
否 |
否 |
pnumber |
商品数量 |
int |
11 |
否 |
否 |
pflag |
商品是否上架 |
int |
20 |
否 |
否 |
用户地址表
字段名 |
描述 |
类型 |
长度 |
空 |
是否主键 |
did |
地址唯一标识 |
varchar |
50 |
否 |
是 |
province |
所在省份 |
varchar |
255 |
否 |
否 |
city |
所在市 |
varchar |
255 |
否 |
否 |
area |
所在县/区 |
varchar |
255 |
否 |
否 |
address |
详细地址 |
varchar |
50 |
否 |
否 |
code |
邮政编码 |
varchar |
50 |
否 |
否 |
phone |
手机 |
varchar |
50 |
否 |
否 |
telephone |
电话 |
varchar |
50 |
否 |
否 |
name |
用户姓名 |
varchar |
255 |
否 |
否 |
商品种类关系表
字段名 |
描述 |
类型 |
长度 |
空 |
是否主键 |
cid |
商品类别 |
varchar |
50 |
否 |
是 |
cname |
类别名称 |
varchar |
255 |
否 |
否 |
用户订单表
字段名 |
描述 |
类型 |
长度 |
空 |
是否主键 |
oid |
订单唯一标识 |
varchar |
50 |
否 |
是 |
total |
订单总价格 |
double |
0 |
否 |
否 |
state |
是否支付 |
int |
11 |
否 |
否 |
address |
地址 |
varchar |
255 |
否 |
否 |
name |
姓名 |
varchar |
50 |
否 |
否 |
telephone |
电话 |
varchar |
255 |
否 |
否 |
uid |
用户唯一标识 |
varchar |
50 |
否 |
否 |
订单项表
字段名 |
描述 |
类型 |
长度 |
空 |
是否主键 |
item_id |
地址唯一标识 |
varchar |
50 |
否 |
是 |
count |
数量 |
Int |
11 |
否 |
否 |
subtotal |
价格 |
double |
0 |
否 |
否 |
pid |
商品唯一标识 |
varchar |
50 |
否 |
否 |
oid |
订单唯一标识 |
varchar |
50 |
否 |
否 |
感谢阅读!