基于JSP+Servlet的在线百货商城系统 - 源码深度解析

JavaJavaScriptHTMLCSSMySQLJSP+Servlet
2026-02-194 浏览

文章摘要

本项目是一款基于JSP与Servlet技术栈开发的在线百货商城系统,旨在为中小型零售企业提供一套功能完整、运行稳定的B2C电子商务解决方案。系统核心解决了传统实体店铺营业时间与空间限制的痛点,通过线上商城的形式帮助商家拓展销售渠道,降低运营成本,同时为消费者提供便捷的24小时不间断购物体验。其核心业...

在当今数字化零售浪潮中,传统中小型百货商店面临着营业时间与物理空间的双重限制。为应对这一挑战,一套基于J2EE经典技术栈的B2C电子商务解决方案应运而生。该系统采用JSP与Servlet作为核心技术框架,结合MySQL数据库,构建了一个功能完备的在线百货商城平台。

系统架构与技术栈设计

该系统严格遵循MVC设计模式,实现了表示层、控制层与业务逻辑层的清晰分离。Servlet作为核心控制器,负责拦截所有HTTP请求,进行初步参数验证后,调用相应的业务逻辑处理单元,最终根据处理结果选择转发至对应的JSP视图页面。

// 用户登录Servlet示例
public class UserLoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
        
        String loginName = request.getParameter("loginName");
        String password = request.getParameter("password");
        
        UserService userService = new UserServiceImpl();
        User user = userService.login(loginName, password);
        
        if(user != null) {
            HttpSession session = request.getSession();
            session.setAttribute("loginUser", user);
            response.sendRedirect("index.jsp");
        } else {
            request.setAttribute("errorMsg", "用户名或密码错误");
            request.getRequestDispatcher("login.jsp").forward(request, response);
        }
    }
}

表示层采用JSP技术,通过嵌入JSTL标签库和EL表达式实现数据的动态渲染,有效避免了在页面中直接编写Java代码,保证了代码的可读性与可维护性。CSS和JavaScript负责前端样式和交互逻辑的实现,为用户提供流畅的购物体验。

数据库设计深度解析

商品表设计分析

easybuy_product表作为系统的核心数据表,其设计体现了电商系统的典型特征:

CREATE TABLE `easybuy_product` (
  `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(255) NOT NULL COMMENT '名称',
  `description` varchar(1024) DEFAULT NULL COMMENT '描述',
  `price` float NOT NULL COMMENT '价格',
  `stock` int(10) NOT NULL COMMENT '库存',
  `categoryLevel1Id` int(10) DEFAULT NULL COMMENT '分类1',
  `categoryLevel2Id` int(10) DEFAULT NULL COMMENT '分类2',
  `categoryLevel3Id` int(10) DEFAULT NULL COMMENT '分类3',
  `fileName` varchar(255) DEFAULT NULL COMMENT '文件名称',
  `isDelete` int(1) DEFAULT 0 COMMENT '是否删除(1:删除 0:未删除)',
  PRIMARY KEY (`id`),
  UNIQUE KEY `PK__EASYBUY___94F6E55132E0915F` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=771 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='商品表'

该表采用三级分类体系,支持灵活的商品分类管理。isDelete字段实现逻辑删除功能,避免物理删除导致的数据丢失风险。价格字段使用float类型,适用于电商场景下的价格计算,但在实际生产环境中建议使用Decimal类型以确保精度。

订单详情表设计

easybuy_order_detail表的设计体现了订单处理的核心理念:

CREATE TABLE `easybuy_order_detail` (
  `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `orderId` int(10) NOT NULL COMMENT '订单主键',
  `productId` int(10) NOT NULL COMMENT '商品主键',
  `quantity` int(10) NOT NULL COMMENT '数量',
  `cost` float NOT NULL COMMENT '消费',
  PRIMARY KEY (`id`),
  UNIQUE KEY `PK__EASYBUY___66E1BD8E2F10007B` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='订单详情表'

该表通过orderId与订单主表关联,productId与商品表关联,实现了订单与商品的多对多关系。cost字段存储下单时的商品价格,确保订单历史价格的准确性,不受后续商品价格变动的影响。

用户表安全设计

easybuy_user表在用户管理方面采用了合理的安全设计:

CREATE TABLE `easybuy_user` (
  `id` int(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `loginName` varchar(255) NOT NULL COMMENT '登录名',
  `userName` varchar(255) NOT NULL COMMENT '用户名',
  `password` varchar(255) NOT NULL COMMENT '密码',
  `sex` int(2) NOT NULL DEFAULT 1 COMMENT '性别(1:男 0:女)',
  `identityCode` varchar(60) DEFAULT NULL COMMENT '身份证号',
  `email` varchar(80) DEFAULT NULL COMMENT '邮箱',
  `mobile` varchar(11) DEFAULT NULL COMMENT '手机',
  `type` int(2) DEFAULT 0 COMMENT '类型(1:后台 0:前台)',
  PRIMARY KEY (`id`),
  UNIQUE KEY `PK__EASYBUY___C96109CC3A81B327` (`loginName`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='用户表'

loginName字段设置唯一约束,防止重复注册。type字段区分前后台用户权限,实现基于角色的访问控制。在实际应用中,密码字段应存储加密后的哈希值而非明文。

核心业务功能实现

购物车模块设计与实现

购物车作为电商系统的核心组件,其实现采用了面向对象的设计思想:

public class Cart {
    private double totalMoney;
    private List<CartItem> cartItems = new ArrayList<CartItem>();
    
    /**
     * 添加到购物车中
     */
    public void addCart(Product product, String num) {
        CartItem cartItem = getExistsItem(product.getId());
        if(cartItem == null) {
            cartItem = new CartItem();
            cartItem.setGoNum(Integer.parseInt(num));
            cartItem.setProduct(product);
            cartItem.setCost(1 * product.getPrice());
            cartItems.add(cartItem);
        } else {
            cartItem.setGoNum(cartItem.getGoNum() + Integer.parseInt(num));
            cartItem.setCost(product.getPrice() * cartItem.getGoNum());
        }
    }
    
    /**
     * 判断商品是否存在于购物车中
     */
    public CartItem getExistsItem(int productId) {
        for (CartItem cartItem : cartItems) {
            if(cartItem.getProduct().getId() == productId) {
                return cartItem;
            }
        }
        return null;
    }
}

购物车页面

购物车模块采用Session存储方案,确保用户在浏览过程中的购物车状态持久化。addCart方法实现了商品的重复添加逻辑,当同一商品多次加入时自动累加数量并重新计算金额。

商品管理功能实现

后台商品管理模块提供了完整的CRUD操作:

public class ProductServiceImpl implements ProductService {
    
    public List<Product> findAllProduct() {
        String sql = "select * from easybuy_product where isDelete=0";
        return BaseDao.executeQuery(Product.class, sql);
    }
    
    public Product findProductById(int id) {
        String sql = "select * from easybuy_product where id=? and isDelete=0";
        List<Product> list = BaseDao.executeQuery(Product.class, sql, id);
        return list.size() > 0 ? list.get(0) : null;
    }
    
    public int updateProduct(Product product) {
        String sql = "update easybuy_product set name=?,description=?,price=?,stock=?,categoryLevel1Id=?,categoryLevel2Id=?,categoryLevel3Id=?,fileName=? where id=?";
        return BaseDao.executeUpdate(sql, product.getName(), product.getDescription(), 
            product.getPrice(), product.getStock(), product.getCategoryLevel1Id(),
            product.getCategoryLevel2Id(), product.getCategoryLevel3Id(),
            product.getFileName(), product.getId());
    }
}

商品管理界面

商品管理采用软删除策略,通过isDelete字段控制商品的显示状态。分类字段支持三级分类体系,满足百货商城复杂的商品分类需求。

订单处理流程实现

订单生成涉及多个数据表的协同操作:

public class OrderServiceImpl implements OrderService {
    
    public boolean addOrder(Order order, List<CartItem> cartItems) {
        Connection conn = null;
        try {
            conn = BaseDao.getConnection();
            conn.setAutoCommit(false);
            
            // 插入订单主表
            String orderSql = "insert into easybuy_order(userId,loginName,userAddress,createTime,cost,serialNumber) values(?,?,?,?,?,?)";
            int orderId = BaseDao.executeInsert(conn, orderSql, order.getUserId(), order.getLoginName(),
                order.getUserAddress(), order.getCreateTime(), order.getCost(), order.getSerialNumber());
            
            // 插入订单明细
            for(CartItem item : cartItems) {
                String detailSql = "insert into easybuy_order_detail(orderId,productId,quantity,cost) values(?,?,?,?)";
                BaseDao.executeUpdate(conn, detailSql, orderId, item.getProduct().getId(), 
                    item.getGoNum(), item.getCost());
                
                // 更新商品库存
                String stockSql = "update easybuy_product set stock=stock-? where id=?";
                BaseDao.executeUpdate(conn, stockSql, item.getGoNum(), item.getProduct().getId());
            }
            
            conn.commit();
            return true;
        } catch (Exception e) {
            if(conn != null) {
                try { conn.rollback(); } catch (SQLException ex) {}
            }
            return false;
        }
    }
}

订单确认页面

订单处理采用数据库事务确保数据一致性,在订单创建过程中同时更新库存信息,防止超卖现象的发生。

用户权限管理实现

系统通过type字段实现前后台用户权限分离:

public class UserFilter implements Filter {
    
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {
        
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        HttpSession session = req.getSession();
        
        User user = (User) session.getAttribute("loginUser");
        String requestURI = req.getRequestURI();
        
        // 后台管理路径需要管理员权限
        if(requestURI.contains("/admin/")) {
            if(user == null || user.getType() != 1) {
                resp.sendRedirect(req.getContextPath() + "/login.jsp");
                return;
            }
        }
        
        chain.doFilter(request, response);
    }
}

管理员登录

权限控制通过Filter实现,对访问后台管理功能的请求进行拦截验证,确保只有管理员身份的用户可以访问相应功能。

实体模型设计

系统采用面向对象的实体模型设计,每个数据库表对应一个实体类:

public class Product {
    private int id;
    private String name;
    private String description;
    private float price;
    private int stock;
    private int categoryLevel1Id;
    private int categoryLevel2Id;
    private int categoryLevel3Id;
    private String fileName;
    private int isDelete;
    
    // Getter和Setter方法
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    
    // 其他Getter和Setter方法...
}

实体类通过封装数据库字段,提供了面向对象的操作接口,业务逻辑层通过操作实体对象来完成数据持久化操作。

数据访问层设计

系统采用统一的数据访问层实现数据库操作:

public class BaseDao {
    
    public static Connection getConnection() {
        Connection conn = null;
        try {
            Context context = new InitialContext();
            DataSource dataSource = (DataSource) context.lookup("java:comp/env/jdbc/easybuy");
            conn = dataSource.getConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    }
    
    public static int executeUpdate(String sql, Object... params) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            conn = getConnection();
            pstmt = conn.prepareStatement(sql);
            for(int i = 0; i < params.length; i++) {
                pstmt.setObject(i + 1, params[i]);
            }
            return pstmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
            return 0;
        } finally {
            closeAll(conn, pstmt, null);
        }
    }
    
    public static <T> List<T> executeQuery(Class<T> clazz, String sql, Object... params) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        List<T> list = new ArrayList<T>();
        
        try {
            conn = getConnection();
            pstmt = conn.prepareStatement(sql);
            for(int i = 0; i < params.length; i++) {
                pstmt.setObject(i + 1, params[i]);
            }
            rs = pstmt.executeQuery();
            
            ResultSetMetaData metaData = rs.getMetaData();
            int columnCount = metaData.getColumnCount();
            
            while(rs.next()) {
                T obj = clazz.newInstance();
                for(int i = 1; i <= columnCount; i++) {
                    String columnName = metaData.getColumnLabel(i);
                    Object value = rs.getObject(i);
                    
                    Field field = clazz.getDeclaredField(columnName);
                    field.setAccessible(true);
                    field.set(obj, value);
                }
                list.add(obj);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeAll(conn, pstmt, rs);
        }
        return list;
    }
}

数据访问层采用反射机制实现通用查询方法,减少了重复代码的编写,提高了开发效率。

系统优化与功能扩展建议

性能优化方向

  1. 数据库连接池优化:采用Druid等高性能连接池替代基础实现,配置合理的连接参数
  2. 查询缓存机制:对热点商品数据实施Redis缓存,减少数据库访问压力
  3. 静态资源分离:将商品图片等静态资源部署至CDN或对象存储服务

功能扩展建议

  1. 支付集成:集成支付宝、微信支付等第三方支付平台,完善交易闭环
  2. 搜索引擎:引入Elasticsearch实现商品全文检索和智能推荐
  3. 移动端适配:开发响应式布局或独立的移动端应用,满足移动购物需求

安全增强措施

  1. 密码加密:使用BCrypt等强哈希算法替代MD5加密
  2. SQL注入防护:全面使用PreparedStatement,添加输入验证过滤器
  3. 会话安全:实现会话超时机制和并发登录控制

该系统作为J2EE经典技术栈的实践案例,展现了MVC架构在Web应用开发中的优势,为中小型零售企业提供了可靠的电商解决方案,同时也为Java Web开发者提供了宝贵的学习参考。通过持续优化和功能扩展,该系统有望成为更加完善的电子商务平台。

本文关键词
JSPServlet在线百货商城源码解析MySQL

上下篇

上一篇
没有更多文章
下一篇
没有更多文章