本次实验旨在通过开发一个基于 B/S 架构的电商平台,深入理解 Web 开发技术,掌握相关知识和技能。具体实验目的如下:
• 系统名称:基于 B/S 架构的 MyShop 商城
• 系统开发背景:
对于用户来说,MyShop 商城的创作目的是为其提供一个完整的电商购物平台,让用户能够方便、快捷地购买自己所需的商品。用户可以通过该平台进行商品浏览、购物车管理、订单管理、支付等操作,同时也可以享受到平台提供的优惠活动和促销信息。MyShop 商城还会为用户提供一个安全、可靠的购物环境。平台会采取各种措施来保护用户的个人信息和支付安全,例如加密传输、防止 SQL 注入、防止 XSS 攻击等。同时,平台也会对商家进行审核和监管,确保商品的质量和售后服务的质量,保障用户的权益。
• 系统用户:会员,游客,管理员。
• 编程环境:Java、Tomcat、MySQL,jsp、CSS、JavaScript 等,其中使用 C3P0 连接池技术管理数据库连接,
MyShop 商城是一个完整的电商购物平台,可通过正确的用户名及其密码进入系统购物。系统分为七大模块,商品展示模块、用户模块、购物车模块、订单模块、支付模块、后台模块。该系统分为用户端和管理端两部分。
• 用户端:主要功能包括浏览商品,加入购物车,支付订单,查询订单。
• 管理端:主要功能包括增加、删除、修改、查找会员、订单信息。
该系统有三个参与者,分别为会员、游客和管理员。会员登录后可以浏览商品信息,将商品加入购物车,下单,支付订单;游客可以浏览商品信息,但在加入购物车时会弹出会员登录注册窗口;管理员登录后可以管理商品信息、会员信息以及订单信息。
需求分析:
首先,需要对 Myshop 商城的需求进行分析,明确商城的功能和特点。商城的主要功能包括用户注册、登录、浏览商品、购物车、下单、支付、订单管理等。商城的特点是需要具备良好的用户体验、安全性、性能等方面的要求。
2. 技术选型:
根据项目需求,选择合适的开发框架和技术。在该项目中,我们选择了 jsp、CSS、js 和 Java 技术作为前端和后端的主要技术栈。这些技术都具有较高的性能和可扩展性,可以满足项目的需求。
3. 开发环境:
在选择好技术栈之后,需要搭建相应的开发环境。我们选用了 IntelliJ IDEA 集成开发环境
4. 数据库设计:
根据项目需求,设计合适的数据库结构,包括商品信息、用户信息、订单信息等, 在设计数据库时,需要考虑到商城的数据量和数据结构,以及数据的安全性和性能。
5. 系统架构设计:
在系统架构设计方面,需要考虑到商城的各个模块之间的交互和调用关系,以及系统的可扩展性和可维护性。可以采用分层架构,将系统分为表示层、业务逻辑层、数据访问层等多个层次,实现各个层之间的解耦。
6. 编码实现:
在代码实现方面,需要按照需求分析和系统架构设计的要求,完成各个模块的代码实现。可以先实现用户注册、登录等基本功能,然后再逐步实现商品浏览、购物车、下单、支付、订单管理等功能。在代码实现过程中,需要注意代码的规范性、可读性和可维护性。
7. 测试调试:
在编码实现完成之后,需要进行测试和部署。在该项目中,我们采用了单元测试和集成测试等测试方式,保证系统的质量。同时,需要将系统部署到服务器上,并进行性能测试和安全测试等,确保各个模块的功能正常运行和系统的稳定性和安全性。
8. 优化完善与维护:
对项目进行优化和完善,提高系统的性能和用户体验, 及时修复系统中出现的问题。
注:本项目代码参考B站一位博主写的
package com.itqf.controller;
import com.itqf.entity.User;
import com.itqf.service.UserService;
import com.itqf.service.impl.UserServiceImpl;
import com.itqf.utils.Base64Utils;
import com.itqf.utils.Constants;
import com.itqf.utils.MD5Utils;
import com.itqf.utils.RandomUtils;
import org.apache.commons.beanutils.BeanUtils;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.Map;
/**
* 用户用户模块的controller
*/
@WebServlet("/user")
public class UserController extends BaseServlet {
public String check(HttpServletRequest request, HttpServletResponse response) throws SQLException {
//1.获取用户名
String username = request.getParameter("username");
if (username == null) {
return Constants.HAS_USER; //不能注册
}
// 2.调用业务逻辑判断用户名是否存在
UserService userService = new UserServiceImpl();
boolean b = userService.checkedUser(username);
// 3.响应字符串 存在:1 不存在:0
if (b) {
//用户存在
return Constants.HAS_USER;
}
return Constants.NOT_HAS_USER;
}
//注册
public String register(HttpServletRequest request, HttpServletResponse response) throws SQLException {
//1.获取用户信息
Map<String, String[]> parameterMap = request.getParameterMap();
User user = new User();
try {
BeanUtils.populate(user, parameterMap); //映射到user
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//2.完善用户信息
user.setUstatus(Constants.USER_NOT_ACTIVE); //默认未激活状态0,激活1
user.setUrole(Constants.ROLE_CUSTOMER); //普通客户0 管理员1
user.setCode(RandomUtils.createActive());//激活码
// 密码加密,md5进行加密
user.setUpassword(MD5Utils.md5(user.getUpassword()));
//3.调用用户业务逻辑进行注册
UserService userService = new UserServiceImpl();
try {
userService.registerUser(user);
} catch (SQLException e) {
e.printStackTrace();
request.setAttribute("registerMsg", "注册失败!");
return Constants.FORWARD + "/register.jsp";
}
//4.响应 注册成功跳转激活页面
return Constants.FORWARD + "/registerSuccess.jsp";
}
public String active(HttpServletRequest request, HttpServletResponse response) throws SQLException {
//1.获取激活码
//已经转成base64
String c = request.getParameter("c");
System.out.println("c="+c);
//base64翻转
String code = Base64Utils.decode(c);
//2.调用激活的业务逻辑
UserService userService = new UserServiceImpl();
int i = userService.activeUser(code);
//3.响应(激活失败(code没有找到) 已经激活 激活成功)
if (i == Constants.ACTIVE_FAIL) {
request.setAttribute("msg", "未激活成功!");
} else if (i == Constants.ACTIVE_SUCCESS) {
request.setAttribute("msg", "激活成功,请登录!");
} else {
request.setAttribute("msg", "已经激活");
}
return Constants.FORWARD + "/message.jsp";
}
/**
* 1.前端提交账号密码和验证码
* 2.对比验证码 成功 ---》 对比账号密码
* 3.对比账号密码
* 失败: --》 回到登录页面 进行提示
* 成功: --》 未激活 登录页面 进行提示
* --》 已激活 程序的首页 将用户放入session共享域
*/
public String login(HttpServletRequest request, HttpServletResponse response) throws SQLException {
//1.获取请求参数(用户名,密码,验证码)
String username = request.getParameter("username");
String password = request.getParameter("password");
String code = request.getParameter("code");//用户输入的验证码
String auto = request.getParameter("auto"); //自动登录标识
//正确的验证码
HttpSession session = request.getSession();
String codestr = (String) session.getAttribute("code");
//2.判断验证码是否正确
// 不考虑大小写比较
// System.out.println("输入:"+code);
// System.out.println("正确"+codestr);
// System.out.println(code == null || !code.equalsIgnoreCase(codestr));
if (code == null || !code.equalsIgnoreCase(codestr)) {
request.setAttribute("msg", "验证码错误");
return Constants.FORWARD + "/login.jsp";
}
//3.调用业务逻辑判断账户密码
UserService userService = new UserServiceImpl();
User user = userService.login(username, password);
//4.响应
//user 等于null证明账号或者密码错误
//user 不为null 但是user的状态是未激活状态
if (user == null) {
request.setAttribute("msg", "账号或者密码错误");
return Constants.FORWARD + "/login.jsp";
}
if (user.getUstatus().equals(Constants.USER_NOT_ACTIVE)) {
request.setAttribute("msg", "账号未激活!");
return Constants.FORWARD + "/login.jsp";
}
//把用户放在共享域session中
session.setAttribute("loginUser", user);
//判断是否勾选自动登录
if (auto == null) {
//没有勾选
//将本地浏览器的存储的cookie清空
Cookie cookie = new Cookie(Constants.AUTO_NAME, "");
cookie.setPath("/");//将 Cookie 的路径设置为根路径,表示该 Cookie 对于整个网站都是可见的
cookie.setMaxAge(0);//最大存活时间设置为 0
response.addCookie(cookie);
} else {
String content = username + Constants.FLAG + password;
content = Base64Utils.encode(content);
//自动登录数据库存储2周
Cookie cookie = new Cookie(Constants.AUTO_NAME, content);
cookie.setPath("/");
cookie.setMaxAge(14 * 24 * 60 * 60);
response.addCookie(cookie);
}
return Constants.REDIRECT + "/index.jsp";
}
/**
* 注销登录!清空数据!跳转到登录页面
*
* @param request
* @param response
* @return
*/
public String logOut(HttpServletRequest request, HttpServletResponse response) {
//1.清空session中用户数据
HttpSession session = request.getSession();
session.removeAttribute("loginUser");
//2.清空和覆盖cooki存储的自动登录
Cookie cookie = new Cookie(Constants.AUTO_NAME, "");
cookie.setPath("/");
cookie.setMaxAge(0);
response.addCookie(cookie);
//3.转发到登录页面
request.setAttribute("msg", "注销登录成功");
return Constants.FORWARD + "/login.jsp";
}
}
package com.itqf.dao;
import com.itqf.entity.User;
import java.sql.SQLException;
/**
* 负责用户模块数据库访问的接口
*/
public interface UserDao {
/**
* 根据用户名查询用户是否存在
* @param username 查询的条件
* @return 返回对应的用户数据
*/
User selectUserByUname(String username) throws SQLException;
/**
* 插入用户数据
* @param user
* @return
* @throws
*/
int insertUser(User user) throws SQLException;
/**
* 根据 激活码code 返回 User
* @param code
* @return
*/
User selectUserByCode(String code) throws SQLException;
/**
* 激活更新数据
* @param uid
* @return
*/
int updataStatusByid(int uid) throws SQLException;
}
package com.itqf.dao.impl;
import com.itqf.dao.UserDao;
import com.itqf.entity.User;
import com.itqf.utils.C3P0Utils;
import com.itqf.utils.Constants;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import java.sql.SQLException;
/**
* 数据库访问实现类
*/
public class UserDaoImpl implements UserDao {
@Override
public User selectUserByUname(String username) throws SQLException {
//1.创建一个QueryRunner对象 获取一个数据库连接池数据源。C3P0是一个流行的开源数据库连接池
QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
//2.执行SQL语句
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 where u_name = ?";
User user = queryRunner.query(sql,new BeanHandler<User>(User.class),username); //将查询结果映射到一个Java对象中
return user;
}
@Override
public int insertUser(User user) throws SQLException {
//1.创建一个QueryRunner对象 获取一个数据库连接池数据源。C3P0是一个流行的开源数据库连接池
QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
//2.执行SQL语句 插入数据
String sql = "insert into user (u_name,u_password,u_sex,u_status," +
"u_code,u_email,u_role) value (?,?,?,?,?,?,?)";
int rows = queryRunner.update(sql, user.getUsername(), user.getUpassword(), user.getUsex(),
user.getUstatus(), user.getCode(), user.getEmail(), user.getUrole());
return rows;
}
@Override
public User selectUserByCode(String code) throws SQLException {
//1.创建一个QueryRunner对象 获取一个数据库连接池数据源。C3P0是一个流行的开源数据库连接池
QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
//2.执行SQL语句
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 where u_code = ?";
User user = queryRunner.query(sql,new BeanHandler<User>(User.class),code); //将查询结果映射到一个Java对象中
return user;
}
@Override
public int updataStatusByid(int uid) throws SQLException {
//1.创建一个QueryRunner对象 获取一个数据库连接池数据源。C3P0是一个流行的开源数据库连接池
QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
String sql = "update user set u_status = ? where u_id = ?";
int row = queryRunner.update(sql, Constants.USER_ACTIVE, uid);
return row;
}
}
package com.itqf.entity;
import java.io.Serializable;
/**
* 对应数据库的用户表
*/
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private int uid; //用户ID
private String username; //对应的是数据库的uname字段 用户账号
private String upassword; //密码
private String usex; //性别
private String ustatus; //用户的激活状态 0 未激活 1 激活
private String code; //邮箱激活码
private String email; //对应的是数据库的uemail字段 邮箱
private int urole; //用户 0 管理员 1
@Override
public String toString() {
return "User{" +
"uid=" + uid +
", username='" + username + '\'' +
", upassword='" + upassword + '\'' +
", usex='" + usex + '\'' +
", ustatus='" + ustatus + '\'' +
", code='" + code + '\'' +
", email='" + email + '\'' +
", urole=" + urole +
'}';
}
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUpassword() {
return upassword;
}
public void setUpassword(String upassword) {
this.upassword = upassword;
}
public String getUsex() {
return usex;
}
public void setUsex(String usex) {
this.usex = usex;
}
public String getUstatus() {
return ustatus;
}
public void setUstatus(String ustatus) {
this.ustatus = ustatus;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getUrole() {
return urole;
}
public void setUrole(int urole) {
this.urole = urole;
}
}
package com.itqf.service;
import com.itqf.entity.User;
import java.sql.SQLException;
/**
* 用户模块对应的业务逻辑接口类
*/
public interface UserService {
/**
* 检测用户名是够存在
* @param username 被检测的用户名
* @return boolean true存在 false不存在
*/
boolean checkedUser(String username) throws SQLException;
/**
* 注册的业务逻辑
* @param user
* @return 插入数据影响的行数
*/
int registerUser(User user) throws SQLException;
/**
* 激活方法
* @param code 根据激活码进行激活
* @return 三个状态 0激活失败 1激活成功 2已经激活
*/
int activeUser(String code) throws SQLException;
/**
* 登录业务
* @param username
* @param password
* @return
*/
User login(String username,String password) throws SQLException;
}
package com.itqf.service.impl;
import com.itqf.dao.UserDao;
import com.itqf.dao.impl.UserDaoImpl;
import com.itqf.entity.User;
import com.itqf.service.UserService;
import com.itqf.utils.Constants;
import com.itqf.utils.EmailUtils;
import com.itqf.utils.MD5Utils;
import java.sql.SQLException;
public class UserServiceImpl implements UserService {
/**
* 验证注册用户名是否可用
* @param username 被检测的用户名
* @return
* @throws SQLException
*/
@Override
public boolean checkedUser(String username) throws SQLException {
//1.创建dao访问对象
UserDao userDao = new UserDaoImpl();
//2.执行结果
User user = userDao.selectUserByUname(username);
//3.处理返回值
if (user != null) {
return true;
}
return false;
}
/**
* 用户注册逻辑
* @param user
* @return
* @throws SQLException
*/
@Override
public int registerUser(User user) throws SQLException {
//1.用户保存到数据库
UserDao userDao = new UserDaoImpl();
int row = userDao.insertUser(user);
//2.发送一封邮件
EmailUtils.sendEmail(user);
return row;
}
/**
* 激活
* @param code 根据激活码进行激活
* @return
* @throws SQLException
*/
@Override
public int activeUser(String code) throws SQLException {
UserDao userDao = new UserDaoImpl();
//1.根据激活码查找用户
User user =userDao.selectUserByCode(code);
if (user==null){
return Constants.ACTIVE_FAIL;//0激活失败
}
//2.判断用户是否激活
if(user.getUstatus().equals(Constants.USER_ACTIVE)){
return Constants.ACTIVE_ALREADY;
}
//3.进行激活操作
int i =userDao.updataStatusByid(user.getUid());
if(i>0){
return Constants.ACTIVE_SUCCESS;
}
return Constants.ACTIVE_FAIL;
}
/**
* 登录业务
* @param username
* @param password
* @return
*/
@Override
public User login(String username, String password) throws SQLException {
//1.需要密码用md5处理
String md5password = MD5Utils.md5(password);
//2.根据用户名查找用户
UserDao userDao = new UserDaoImpl();
User user = userDao.selectUserByUname(username);
if (user != null && user.getUpassword().equals(md5password)) {
return user;
}
return null;
}
}
下载链接
https://download.csdn.net/download/weixin_66397563/87977577