家居网购项目
Posted Al_tair
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了家居网购项目相关的知识,希望对你有一定的参考价值。
家居网购项目
大家好呀!我是小笙~ 该家居网购的技术栈是javaweb开发,我觉得这个是对之前学习的知识的一个总结和输出,是个很好的自我学习反馈的过程.
家居网购项目
家居网购-程序框架图
使用分层模式: 分层的目的是为了解耦,降低代码的耦合度,有利项目的维护和升级
三层架构MVC
MVC 全称∶ Model 模型、View 视图、 Controller 控制器
MVC 的理念是将软件代码拆分成为组件,单独开发,组合使用(目的还是为了解耦合), 也有很多落地的框架比如 SpringMVC
- MVC 最早出现在 JavaEE 三层中的 Web 层,它可以有效的指导 WEB 层的代码如何有效 分离,单独工作
- 后面业务复杂度越来越高, model 逐渐分层/组件化 (service + dao)
项目准备
需要引入的jar包
程序框架图
页面展示
首页展示
登录注册页面
家居后台管理页面
购物车页面
订单生成页面
功能实现
注册功能
1.设计用户表
# 创建数据库
DROP DATABASE IF EXISTS home_shopping;
CREATE DATABASE home_shopping;
USE home_shopping;
# 创建用户表
CREATE TABLE member(
`id` INT PRIMARY KEY AUTO_INCREMENT, # id
`username` VARCHAR(10) NOT NULL UNIQUE, # 用户名
`password` VARCHAR(32) NOT NULL, # 密码
`email` VARCHAR(64), # 邮箱
`user_state` TINYINT NOT NULL DEFAULT 0 # 用户模式 0 会员 1 管理员 -1 未登录
)CHARSET utf8 ENGINE INNODB;
INSERT INTO member(`username`,`password`,`email`,`user_state`) VALUES('Al_tair',MD5('luo1234567'),'lns@qq.com',1);
INSERT INTO member(`username`,`password`,`email`,`user_state`) VALUES('admins',MD5('1234567'),'1079936146@qq.com',0);
SELECT * FROM member;
2.Dao层对数据库的CRUD
public interface MemberDao
/**
* 添加会员用户信息
*/
public boolean addUserInfo(Member member);
/**
* 查询是否有该用户名的会员用户
*/
public boolean queryUserInfo(String username);
/**
* 查询有该用户名和密码的会员用户信息
*/
public Member queryUserInfo(String username,String password);
// 备注:实现代码略,记得每次写完实现代码使用Junit测试
3.Service层对业务的操作
public interface MemberService
/**
* 注册用户
*/
public boolean registerUser(Member member);
/**
* 是否有存在该用户
*/
public boolean isExistUser(String username);
/**
* 用户登录
*/
public Member login(String username,String password);
// 备注:实现代码略,记得每次写完实现代码使用Junit测试
4.前端页面效果
<!-- 截图部分重点 -->
<div class="login-register-form">
<!-- 错误提醒 -->
<span class="errorMsg"
style="float: right; font-weight: bold; font-size: 20pt; margin-left: 10px;">
</span>
<form action="memberServlet" method="post">
<input type="hidden" name="action" value="register">
<input type="text" id="username" name="username" placeholder="Username"/>
<input type="password" id="password" name="password" placeholder="输入密码"/>
<input type="password" id="repwd" name="repassword" placeholder="确认密码"/>
<input name="email" id="email" placeholder="电子邮件" type="email"/>
<input type="text" id="code" name="code" style="width: 50%" placeholder="验证码"/>
<img class="codeImgRegister" alt="" src="">
<div class="button-box">
<button type="submit" id="register-btn"><span>会员注册</span></button>
</div>
</form>
</div>
5.前端页面校验(JQuery库)
-
验证用户名:必须字母,数字下划线组成,并且长度为 6 到 10 位
/^[a-zA-Z0-9_]6,10$/
-
验证密码:必须由字母,数字下划线组成,并且长度为 6 到 10 位
-
邮箱格式验证:常规验证即可 (正则表达式 )
/^[A-Za-z0-9]+([_\\.][A-Za-z0-9]+)*@([A-Za-z0-9\\-]+\\.)+[A-Za-z]2,6$/
-
验证码:校验
导入包
表单重复提交情况:
- 提交完表单。服务器使用请求转发进行页面跳转。用户刷新(F5),会发起最后一 次的请求, 造成表单重复提交问题。解决:用重定向
- 用户正常提交,由于网络延迟等原因,未收到服务器的响应,这时,用户着急多 点了几次提交操作,也会造成表单重复提交。解决: 验证码
- 用户正常提交,服务器也没有延迟,但是提交完成后,用户回退浏览器。重新提 交。也会造成表单重复提交,解决:验证码
<!-- 点击校验码,更新校验码 --> $(".codeImgRegister").click(function() this.src="<%=request.getContextPath() + "/"%>kaptchaServlet?d=" + new Date(); )
-
校验优化:Ajax异步请求
<script type="text/javascript"> // Ajax异步请求:这里是登录用户的校验,同理注册也是可以的 $("#LoginUsername").blur(function() $.getJSON( "memberServlet", action:"IsExistUser", username:$("#LoginUsername").val(), , function (data,state,XHttp) if(!data.IsExistUser) $("span.errorMsg").text("用户名不存在!"); else $("span.errorMsg").text(""); ) ) </script>
6.后端校验
if(username == null || password == null || email == null || repassword == null)
response.sendRedirect(getServletContext().getContextPath() + "/views/member/register_fail.jsp");
return;
// 用户名格式校对
String pattern = "^[a-zA-Z0-9_]6,10$";
if(Pattern.matches(pattern,username))
System.out.println("用户名格式正确");
else
System.out.println("用户名格式不正确");
response.sendRedirect(getServletContext().getContextPath() + "/views/member/register_fail.jsp");
return;
// 密码格式校对
pattern = "^[a-zA-Z0-9_]6,10$";
if(Pattern.matches(pattern,password))
System.out.println("密码格式正确");
else
System.out.println("密码格式不正确");
response.sendRedirect(getServletContext().getContextPath() + "/views/member/register_fail.jsp");
return;
// 输入两次密码是否相同
if(!password.equals(repassword))
System.out.println("输入两次密码不相同!");
response.sendRedirect(getServletContext().getContextPath() + "/views/member/register_fail.jsp");
return;
// 邮箱格式校对
pattern = "\\\\w+@\\\\w+\\\\.[a-z]+(\\\\.[a-z]+)?";
if(Pattern.matches(pattern,email))
System.out.println("邮箱格式正确");
else
System.out.println("邮箱格式不正确");
response.sendRedirect(getServletContext().getContextPath() + "/views/member/register_fail.jsp");
return;
// 获取验证码
HttpSession session = request.getSession();
Object realCode = session.getAttribute(KAPTCHA_SESSION_KEY);
// 立即删除session中该属性
session.removeAttribute(KAPTCHA_SESSION_KEY);
if(realCode == null || code == null || !code.equalsIgnoreCase((String)realCode))
System.out.println("验证码不正确");
response.sendRedirect(getServletContext().getContextPath() + "/views/member/register_fail.jsp");
return;
7.注册页面后端需求分析
-
会员注册信息,前端验证通过后,提交给服务器
-
如果用户名在数据库中已经存在,后台给出提示信息,并返回重新注册
-
如果用户名没有在数据库中,完成注册,并返回注册成功的页面
-
-
注册密码为 md5 加密
登录功能
1.前端页面效果
<div class="login-register-form">
<!-- 显示错误信息 -->
<span style="font-size: 18pt;font-weight: bold;float: right;color: red">
<span class="errorMsg"
style="float: right; font-weight: bold; font-size: 20pt; margin-left: 10px;">
</span>
</span>
<form action="memberServlet" method="post">
<input type="hidden" name="action" value="login">
<input type="text" id="LoginUsername" name="username" value="$requestScope.get("username")" placeholder="Username"/>
<input type="password" name="password" placeholder="Password"/>
<input type="text" id="code2" name="code" style="width: 50%" placeholder="验证码"/>
<img class="codeImgLogin" alt="" src="kaptchaServlet">
<div class="button-box">
<div class="login-toggle-btn">
<input type="checkbox"/>
<a class="flote-none" href="javascript:void(0)">Remember me</a>
<a href="#">Forgot Password?</a>
</div>
<button type="submit" id="login_btn"><span>Login</span></button>
</div>
</form>
</div>
2.后端需求分析
-
分别校验输入的用户名和密码是否符合格式
-
通过用户名和密码去数据库查找数据
-
如果找到数据,跳转到登录成功的页面
-
如果没有找到数据或者用户名密码格式不对,都会返回登录页面并且显示
-
3.优化Servlet,将处理请求和分发请求分开
-
问题提出:其实不管是会员注册还是会员登录都是对会员用户的数据操作,但是却分出了两个Servlet,接下来我们尝试解决web层的优化
-
方案一:通过隐藏域的值来判断是login还是register
<input type="hidden" name="action" value="register">
String action = request.getParameter("action"); if("register".equals(action)) RegisterServlet(request,response); else if("login".equals(action)) LoginServlet(request,response);
问题存在:虽然分开了处理请求和分发请求,但是本质还是在一个Servlet操作,同时随着业务的拓展,会存在代码复用的问题
-
方案二:反射 + 模板设计模式 + 动态绑定
-
就是将接收http请求和分发请求交给父类BasicServlet,将处理请求交给子类
public abstract class BasicServlet extends HttpServlet @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException // 注意action值要和方法名一致 String action = request.getParameter(以上是关于家居网购项目的主要内容,如果未能解决你的问题,请参考以下文章
-
-