基于JSP+Servlet的水果在线销售系统 - 源码深度解析

JavaJavaScriptHTMLCSSMySQLJSP+Servlet
2026-03-243 浏览

文章摘要

本项目是一款基于JSP与Servlet技术栈构建的水果在线销售系统,专为中小型水果零售商或个体商户设计,旨在提供一个功能完整、易于部署的线上销售解决方案。其核心业务价值在于帮助传统水果商家以较低的技术门槛和成本快速切入电商领域,有效解决实体店铺营业时间与地域限制的痛点,实现24小时不间断营业,拓宽客...

在传统零售业数字化转型的浪潮中,生鲜水果行业因其产品特性面临着独特的挑战与机遇。实体店铺受限于营业时间和物理位置,难以有效拓展客户群体和销售规模。针对这一市场需求,一个基于JSP+Servlet技术栈的B/S架构在线销售平台应运而生。该系统专为中小型水果商户设计,实现了从商品展示、购物车管理到订单处理的全流程线上化,为传统水果店提供了低成本、高效率的电商解决方案。

该系统采用经典的MVC架构模式,将业务逻辑、数据展示和用户交互清晰分离。表现层使用JSP技术结合JSTL标签库动态生成页面内容,控制层通过Servlet集中处理各类业务请求,数据持久层则基于JDBC实现与MySQL数据库的稳定交互。这种分层架构不仅保证了系统的可维护性和扩展性,还显著降低了技术门槛,使不具备前沿技术背景的小型商户也能快速部署使用。

系统首页

数据库架构设计深度解析

系统的数据模型围绕核心业务实体精心构建,共设计6张数据表,形成了完整的业务数据闭环。其中fruit表作为商品信息核心载体,其设计体现了对水果商品特性的充分考虑:

CREATE TABLE fruit (
    fruitId INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL,
    price DECIMAL(8,2) NOT NULL,
    currentPrice DECIMAL(8,2) NOT NULL,
    picture VARCHAR(100) DEFAULT 'moren.jpg',
    categoryId INT NOT NULL,
    hit INT DEFAULT 0,
    introduce VARCHAR(200) DEFAULT '暂无介绍',
    stock INT DEFAULT 0,
    startTime DATETIME DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (fruitId),
    FOREIGN KEY (categoryId) REFERENCES category(categoryId)
);

该表结构设计了price(原价)和currentPrice(现价)双价格字段,支持灵活的促销策略实施。hit字段记录商品点击量,为热门商品推荐提供数据支撑。stock库存字段确保销售过程中库存数据的实时准确性,而startTime上架时间字段则便于新品推广和商品生命周期管理。

orders订单表的设计同样体现了电商业务的复杂性:

CREATE TABLE orders (
    orderId INT NOT NULL AUTO_INCREMENT,
    orderNo VARCHAR(20) NOT NULL UNIQUE,
    userId INT NOT NULL,
    orderTime DATETIME DEFAULT CURRENT_TIMESTAMP,
    orderPrice DECIMAL(8,2) NOT NULL,
    orderState INT DEFAULT 0,
    name VARCHAR(20) NOT NULL,
    tel VARCHAR(11) NOT NULL,
    address VARCHAR(50) NOT NULL,
    PRIMARY KEY (orderId),
    FOREIGN KEY (userId) REFERENCES user(userId)
);

订单编号orderNo采用独立字段设计并设置唯一约束,既保证了业务标识的独立性,又便于订单查询和跟踪。订单状态orderState使用整型字段,通过枚举值实现状态机管理,支持待付款、已付款、配送中、已完成等完整状态流转。收货人信息的冗余存储有效解决了用户修改个人信息对历史订单的影响。

核心业务逻辑实现

用户认证模块采用Session机制实现状态管理。用户登录成功后,系统将用户对象存入Session,并在后续请求中通过过滤器进行权限验证:

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

购物车功能基于Session实现,确保用户交互的实时性和流畅性。购物车管理器采用单例模式,维护商品项集合并计算总价:

public class Cart {
    private Map<Integer, CartItem> items = new HashMap<>();
    
    public void addItem(Fruit fruit, int quantity) {
        CartItem item = items.get(fruit.getFruitId());
        if(item == null) {
            item = new CartItem(fruit, quantity);
            items.put(fruit.getFruitId(), item);
        } else {
            item.setQuantity(item.getQuantity() + quantity);
        }
    }
    
    public BigDecimal getTotalPrice() {
        BigDecimal total = BigDecimal.ZERO;
        for(CartItem item : items.values()) {
            total = total.add(item.getSubTotal());
        }
        return total;
    }
}

商品搜索功能支持按名称关键字和分类联合查询,通过JDBC实现动态SQL构建:

public List<Fruit> searchFruits(String keyword, Integer categoryId) throws SQLException {
    StringBuilder sql = new StringBuilder("SELECT * FROM fruit WHERE 1=1");
    List<Object> params = new ArrayList<>();
    
    if(keyword != null && !keyword.trim().isEmpty()) {
        sql.append(" AND name LIKE ?");
        params.add("%" + keyword + "%");
    }
    
    if(categoryId != null && categoryId > 0) {
        sql.append(" AND categoryId = ?");
        params.add(categoryId);
    }
    
    sql.append(" ORDER BY hit DESC");
    
    try(Connection conn = DataSourceUtil.getConnection();
        PreparedStatement pstmt = conn.prepareStatement(sql.toString())) {
        
        for(int i = 0; i < params.size(); i++) {
            pstmt.setObject(i + 1, params.get(i));
        }
        
        ResultSet rs = pstmt.executeQuery();
        return resultSetToFruitList(rs);
    }
}

订单生成过程涉及事务处理,确保数据一致性。订单主表与订单明细表在一个事务中同时更新:

@Transactional
public boolean createOrder(Order order, List<OrderItem> items) {
    try {
        // 插入订单主表
        orderDao.insertOrder(order);
        
        // 插入订单明细
        for(OrderItem item : items) {
            orderDao.insertOrderItem(item);
            // 同步更新库存
            fruitDao.updateStock(item.getFruitId(), -item.getQuantity());
        }
        
        return true;
    } catch (SQLException e) {
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        return false;
    }
}

后台管理系统提供完整的商品管理界面,支持商品信息的增删改查操作:

商品管理

订单处理流程优化

系统实现了完整的订单状态管理机制,管理员可以在后台查看和处理所有订单:

订单管理

订单状态更新操作通过专门的Servlet处理,确保状态流转的准确性:

public class UpdateOrderStateServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        int orderId = Integer.parseInt(request.getParameter("orderId"));
        int newState = Integer.parseInt(request.getParameter("state"));
        
        OrderService orderService = new OrderServiceImpl();
        boolean success = orderService.updateOrderState(orderId, newState);
        
        if(success) {
            response.getWriter().write("success");
        } else {
            response.getWriter().write("error");
        }
    }
}

用户可以在个人中心查看订单历史记录和当前状态:

我的订单

系统安全与性能考量

用户输入验证通过多层过滤机制实现。前端使用JavaScript进行基本验证,后端Servlet进行业务逻辑验证:

public class OrderValidator {
    public static ValidationResult validateOrder(Order order) {
        ValidationResult result = new ValidationResult();
        
        if(order.getOrderPrice().compareTo(BigDecimal.ZERO) <= 0) {
            result.addError("订单金额必须大于0");
        }
        
        if(order.getName() == null || order.getName().trim().length() < 2) {
            result.addError("收货人姓名至少2个字符");
        }
        
        // 手机号格式验证
        if(!Pattern.matches("^1[3-9]\\d{9}$", order.getTel())) {
            result.addError("手机号格式不正确");
        }
        
        return result;
    }
}

数据库连接管理通过连接池技术优化性能,避免频繁创建和关闭连接的开销:

public class DataSourceUtil {
    private static BasicDataSource dataSource;
    
    static {
        dataSource = new BasicDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/fruit_db?useSSL=false");
        dataSource.setUsername("root");
        dataSource.setPassword("password");
        dataSource.setInitialSize(5);
        dataSource.setMaxTotal(20);
        dataSource.setMaxIdle(10);
        dataSource.setMinIdle(5);
    }
    
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
}

技术架构优化方向

虽然当前系统已实现核心电商功能,但在以下方面仍有优化空间:

  1. 缓存层引入:使用Redis等内存数据库缓存热门商品数据、分类信息等静态数据,降低数据库访问压力。可设计缓存策略,如商品信息缓存过期时间设置为30分钟,分类信息缓存时间可适当延长。

  2. 全文搜索优化:集成Elasticsearch实现更高效的商品搜索,支持拼音搜索、同义词扩展、搜索词推荐等高级功能。通过建立商品索引,提升搜索响应速度和准确性。

  3. 异步任务处理:使用消息队列处理订单生成后的后续操作,如库存扣减、积分计算、短信通知等。这有助于提高系统吞吐量和用户体验。

  4. 微服务架构重构:将单体应用拆分为用户服务、商品服务、订单服务、支付服务等独立微服务,提升系统可扩展性和维护性。通过API网关统一管理服务接口。

  5. 移动端适配:开发响应式前端界面或独立的移动App,满足移动端用户的使用习惯。可采用Vue.js或React等现代前端框架重构用户界面。

该系统作为传统水果零售业数字化转型的典型解决方案,通过合理的技术选型和架构设计,在保证功能完整性的同时兼顾了实施成本。其模块化设计和清晰的代码结构为后续功能扩展和技术升级奠定了良好基础,展现了Java Web技术在中小企业电商应用中的实用价值。

本文关键词
JSPServlet水果在线销售系统MVC架构数据库设计

上下篇

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