基于JSP+Servlet的在线汽车租赁预订系统 - 源码深度解析

JavaJavaScriptHTMLCSSMySQLJSP+Servlet
2026-02-102 浏览

文章摘要

本项目是一款基于JSP和Servlet技术构建的在线汽车租赁预订系统,旨在为传统汽车租赁行业提供一个高效、便捷的数字化管理及服务解决方案。系统核心业务价值在于彻底改变了传统依赖人工记录和电话沟通的低效模式,通过集中化的信息管理,解决了客户找车难、门店管理乱、预订流程繁琐等行业痛点。它将车辆资源、客户...

在当今数字化浪潮下,传统汽车租赁行业面临着转型升级的迫切需求。客户找车难、门店管理效率低下、预订流程繁琐等痛点长期制约着行业发展。为此,我们设计并实现了一套企业级汽车租赁管理平台,通过JSP+Servlet技术栈构建了一个完整的在线租赁解决方案。

系统架构与技术栈选型

该平台采用经典的MVC架构模式,实现了业务逻辑、数据展示和用户交互的清晰分离。技术栈选择基于稳定性和成熟度考虑:后端使用Java Servlet处理业务逻辑,JSP负责视图渲染,MySQL作为数据存储层,前端采用HTML+CSS+JavaScript组合。

// Servlet控制器示例
@WebServlet("/car/rent")
public class CarRentServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
        
        String carId = request.getParameter("carId");
        String startDate = request.getParameter("startDate");
        String endDate = request.getParameter("endDate");
        String userId = (String) request.getSession().getAttribute("userId");
        
        // 参数校验
        if (Validator.isEmpty(carId) || Validator.isEmpty(startDate)) {
            request.setAttribute("error", "参数不完整");
            request.getRequestDispatcher("/error.jsp").forward(request, response);
            return;
        }
        
        // 业务逻辑处理
        CarRentService rentService = new CarRentService();
        boolean success = rentService.processRental(userId, carId, startDate, endDate);
        
        if (success) {
            response.sendRedirect("/order/success.jsp");
        } else {
            request.setAttribute("error", "租赁失败,车辆可能已被预订");
            request.getRequestDispatcher("/car/list.jsp").forward(request, response);
        }
    }
}

数据库连接采用JDBC连接池技术,确保高并发场景下的性能稳定:

// 数据库连接池配置
public class DatabaseConnection {
    private static DataSource dataSource;
    
    static {
        MysqlDataSource mysqlDS = new MysqlDataSource();
        mysqlDS.setURL("jdbc:mysql://localhost:3306/car_rental");
        mysqlDS.setUser("username");
        mysqlDS.setPassword("password");
        mysqlDS.setCachePrepStmts(true);
        mysqlDS.setPrepStmtCacheSize(250);
        mysqlDS.setPrepStmtCacheSqlLimit(2048);
        dataSource = mysqlDS;
    }
    
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
}

数据库设计深度解析

商品表(goods)设计优化

商品表作为系统的核心数据表,设计考虑了扩展性和查询效率:

CREATE TABLE `goods` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `goodno` varchar(255) DEFAULT NULL COMMENT '商品编号',
  `goodname` varchar(255) DEFAULT NULL COMMENT '商品名称',
  `fid` varchar(255) DEFAULT NULL COMMENT '父分类ID',
  `sid` varchar(255) DEFAULT NULL COMMENT '子分类ID',
  `price` varchar(255) DEFAULT NULL COMMENT '商品价格',
  `note` text DEFAULT NULL COMMENT '商品描述',
  `saver` varchar(255) DEFAULT NULL COMMENT '保存人',
  `savetime` varchar(255) DEFAULT NULL COMMENT '保存时间',
  `shstatus` varchar(255) DEFAULT NULL COMMENT '审核状态',
  `istj` varchar(255) DEFAULT NULL COMMENT '是否推荐',
  `tprice` varchar(255) DEFAULT NULL COMMENT '特价',
  `filename` varchar(255) DEFAULT NULL COMMENT '图片文件名',
  `delstatus` varchar(255) DEFAULT NULL COMMENT '删除状态',
  `salestatus` varchar(255) DEFAULT NULL COMMENT '销售状态',
  `goodpp` varchar(255) DEFAULT NULL COMMENT '商品品牌',
  PRIMARY KEY (`id`),
  KEY `idx_goodno` (`goodno`),
  KEY `idx_fid_sid` (`fid`,`sid`),
  KEY `idx_shstatus` (`shstatus`),
  KEY `idx_salestatus` (`salestatus`)
) ENGINE=InnoDB AUTO_INCREMENT=58 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='商品表'

设计亮点分析:

  1. 索引策略优化:针对商品编号、分类ID组合、审核状态和销售状态建立了复合索引,显著提升查询性能
  2. 字段类型选择:价格字段采用varchar类型,支持灵活的价格格式(如区间价格、折扣价格)
  3. 状态管理:通过多个状态字段实现商品的精细化管理,支持软删除机制
  4. 扩展性考虑:预留了品牌字段和推荐标识,为后续营销功能扩展奠定基础

库存记录表(kcrecord)设计

库存记录表实现了车辆库存的精确追踪:

CREATE TABLE `kcrecord` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `gid` varchar(255) DEFAULT NULL COMMENT '商品ID',
  `happennum` varchar(255) DEFAULT NULL COMMENT '发生数量',
  `type` varchar(255) DEFAULT NULL COMMENT '操作类型',
  `savetime` varchar(255) DEFAULT NULL COMMENT '保存时间',
  PRIMARY KEY (`id`),
  KEY `idx_gid` (`gid`),
  KEY `idx_savetime` (`savetime`)
) ENGINE=InnoDB AUTO_INCREMENT=92 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='库存记录表'

该表通过操作类型字段区分库存变动原因(租赁、归还、维修等),配合时间索引可实现库存历史追溯和统计分析。

核心功能实现详解

车辆租赁业务流程

租赁业务是系统的核心功能,涉及复杂的状态管理和库存控制:

// 租赁服务实现
public class CarRentService {
    private GoodsDAO goodsDAO = new GoodsDAO();
    private OrderDAO orderDAO = new OrderDAO();
    private KcrecordDAO kcrecordDAO = new KcrecordDAO();
    
    public boolean processRental(String userId, String carId, 
                               String startDate, String endDate) {
        Connection conn = null;
        try {
            conn = DatabaseConnection.getConnection();
            conn.setAutoCommit(false);
            
            // 检查车辆可用性
            Goods car = goodsDAO.findById(conn, carId);
            if (!"上架".equals(car.getSalestatus()) || 
                !"已审核".equals(car.getShstatus())) {
                return false;
            }
            
            // 创建订单
            Order order = new Order();
            order.setUserId(userId);
            order.setGoodsId(carId);
            order.setStartDate(startDate);
            order.setEndDate(endDate);
            order.setStatus("待支付");
            order.setCreateTime(new Date());
            
            boolean orderSuccess = orderDAO.save(conn, order);
            if (!orderSuccess) {
                conn.rollback();
                return false;
            }
            
            // 更新库存记录
            Kcrecord record = new Kcrecord();
            record.setGid(carId);
            record.setHappennum("-1"); // 减少库存
            record.setType("租赁出库");
            record.setSavetime(new Date().toString());
            
            boolean kcSuccess = kcrecordDAO.save(conn, record);
            if (!kcSuccess) {
                conn.rollback();
                return false;
            }
            
            conn.commit();
            return true;
            
        } catch (Exception e) {
            if (conn != null) {
                try { conn.rollback(); } catch (SQLException ex) {}
            }
            return false;
        } finally {
            if (conn != null) {
                try { conn.close(); } catch (SQLException e) {}
            }
        }
    }
}

创建订单界面

订单管理模块

订单管理实现了完整的生命周期控制,从创建到完成的全流程跟踪:

<%-- 订单列表JSP页面 --%>
<%@ page import="java.util.List,com.carrental.model.Order" %>
<%
List<Order> orders = (List<Order>) request.getAttribute("orders");
%>

<table class="table table-striped">
    <thead>
        <tr>
            <th>订单编号</th>
            <th>车辆信息</th>
            <th>租赁时间</th>
            <th>订单状态</th>
            <th>操作</th>
        </tr>
    </thead>
    <tbody>
        <% for(Order order : orders) { %>
        <tr>
            <td><%= order.getOrderNo() %></td>
            <td>
                <img src="<%= order.getGoods().getFilename() %>" width="50">
                <%= order.getGoods().getGoodname() %>
            </td>
            <td><%= order.getStartDate() %> 至 <%= order.getEndDate() %></td>
            <td>
                <span class="status-<%= order.getStatus() %>">
                    <%= order.getStatus() %>
                </span>
            </td>
            <td>
                <a href="/order/detail?id=<%= order.getId() %>" class="btn btn-info">详情</a>
                <% if("待支付".equals(order.getStatus())) { %>
                <a href="/payment/create?orderId=<%= order.getId() %>" class="btn btn-warning">支付</a>
                <% } %>
            </td>
        </tr>
        <% } %>
    </tbody>
</table>

订单管理界面

车辆库存管理

库存管理采用实时追踪机制,确保数据准确性:

// 库存查询服务
public class InventoryService {
    
    public int getCurrentStock(String goodsId) {
        String sql = "SELECT SUM(CAST(happennum AS SIGNED)) as total " +
                    "FROM kcrecord WHERE gid = ?";
        
        try (Connection conn = DatabaseConnection.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            
            pstmt.setString(1, goodsId);
            ResultSet rs = pstmt.executeQuery();
            
            if (rs.next()) {
                return rs.getInt("total");
            }
            return 0;
            
        } catch (SQLException e) {
            e.printStackTrace();
            return -1;
        }
    }
    
    public List<Kcrecord> getStockHistory(String goodsId, Date startDate, Date endDate) {
        List<Kcrecord> records = new ArrayList<>();
        String sql = "SELECT * FROM kcrecord WHERE gid = ? AND savetime BETWEEN ? AND ? " +
                    "ORDER BY savetime DESC";
        
        try (Connection conn = DatabaseConnection.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            
            pstmt.setString(1, goodsId);
            pstmt.setTimestamp(2, new Timestamp(startDate.getTime()));
            pstmt.setTimestamp(3, new Timestamp(endDate.getTime()));
            
            ResultSet rs = pstmt.executeQuery();
            while (rs.next()) {
                Kcrecord record = new Kcrecord();
                record.setId(rs.getLong("id"));
                record.setGid(rs.getString("gid"));
                record.setHappennum(rs.getString("happennum"));
                record.setType(rs.getString("type"));
                record.setSavetime(rs.getString("savetime"));
                records.add(record);
            }
            
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return records;
    }
}

车辆库存管理

用户会话管理

系统采用Session机制管理用户状态,确保安全性:

// 登录验证Servlet
@WebServlet("/user/login")
public class LoginServlet extends HttpServlet {
    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
        
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String userType = request.getParameter("userType");
        
        UserService userService = new UserService();
        User user = userService.authenticate(username, password, userType);
        
        if (user != null) {
            HttpSession session = request.getSession();
            session.setAttribute("userId", user.getId());
            session.setAttribute("username", user.getUsername());
            session.setAttribute("userType", userType);
            session.setMaxInactiveInterval(30 * 60); // 30分钟超时
            
            // 记录登录日志
            LogService.logLogin(user.getId(), request.getRemoteAddr());
            
            if ("admin".equals(userType)) {
                response.sendRedirect("/admin/dashboard.jsp");
            } else {
                response.sendRedirect("/user/dashboard.jsp");
            }
        } else {
            request.setAttribute("error", "用户名或密码错误");
            request.getRequestDispatcher("/login.jsp").forward(request, response);
        }
    }
}

用户登录界面

实体模型设计

系统采用面向对象的设计思想,构建了完整的实体模型体系:

// 商品实体类
public class Goods {
    private Long id;
    private String goodno;
    private String goodname;
    private String fid;
    private String sid;
    private String price;
    private String note;
    private String saver;
    private String savetime;
    private String shstatus;
    private String istj;
    private String tprice;
    private String filename;
    private String delstatus;
    private String salestatus;
    private String goodpp;
    
    // getter和setter方法
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    
    public String getGoodno() { return goodno; }
    public void setGoodno(String goodno) { this.goodno = goodno; }
    
    // 其他getter/setter方法...
    
    // 业务方法
    public boolean isAvailable() {
        return "上架".equals(salestatus) && "已审核".equals(shstatus) && !"是".equals(delstatus);
    }
    
    public BigDecimal getCurrentPrice() {
        if (tprice != null && !tprice.trim().isEmpty()) {
            return new BigDecimal(tprice);
        }
        return new BigDecimal(price);
    }
}

功能展望与优化方向

基于当前系统架构,未来可从以下几个方向进行优化和功能扩展:

1. 引入Redis缓存层

实现思路:将热点数据如车辆信息、用户会话、配置信息等存入Redis,减轻数据库压力。

// 缓存服务示例
@Service
public class RedisCacheService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    public Goods getGoodsFromCache(String goodsId) {
        String key = "goods:" + goodsId;
        Goods goods = (Goods) redisTemplate.opsForValue().get(key);
        if (goods == null) {
            goods = goodsDAO.findById(goodsId);
            if (goods != null) {
                redisTemplate.opsForValue().set(key, goods, Duration.ofHours(1));
            }
        }
        return goods;
    }
}

2. 微服务架构改造

实现思路:将单体应用拆分为用户服务、订单服务、库存服务、支付服务等微服务,提升系统可扩展性和维护性。

3. 移动端适配开发

实现思路:开发React Native或Flutter移动应用,提供更好的移动端用户体验,支持扫码租车等移动特色功能。

4. 智能推荐系统

实现思路:基于用户历史租赁数据和协同过滤算法,实现个性化车辆推荐:

public class RecommendationService {
    public List<Goods> recommendCars(String userId) {
        // 基于用户历史行为分析
        List<RentalHistory> history = rentalDAO.findUserHistory(userId);
        
        // 协同过滤算法实现
        Map<String, Double> userPreferences = analyzePreferences(history);
        
        // 返回匹配度最高的车辆
        return goodsDAO.findByPreferences(userPreferences);
    }
}

5. 大数据分析平台

实现思路:集成ELK栈或ClickHouse,构建租赁业务数据分析平台,为运营决策提供数据支持。

系统安全与性能优化

系统在安全性方面采用了多重防护措施:

// SQL注入防护
public class SQLInjectionProtection {
    public static boolean isValidParameter(String input) {
        if (input == null) return false;
        
        // 检测SQL注入关键词
        String[] sqlKeywords = {"select", "insert", "delete", "update", "drop", 
                               "union", "exec", "truncate"};
        String lowerInput = input.toLowerCase();
        
        for (String keyword : sqlKeywords) {
            if (lowerInput.contains(keyword) && 
                lowerInput.matches(".*\\b" + keyword + "\\b.*")) {
                return false;
            }
        }
        return true;
    }
}

// XSS防护
public class XSSProtection {
    public static String filterXSS(String input) {
        if (input == null) return null;
        
        return input.replaceAll("<", "&lt;")
                   .replaceAll(">", "&gt;")
                   .replaceAll("\"", "&quot;")
                   .replaceAll("'", "&#x27;")
                   .replaceAll("/", "&#x2F;");
    }
}

性能优化方面,系统采用了数据库连接池、静态资源缓存、页面静态化等技术:

<!-- web.xml中的缓存配置 -->
<filter>
    <filter-name>ExpiresFilter</filter-name>
    <filter-class>org.apache.catalina.filters.ExpiresFilter</filter-class>
    <init-param>
        <param-name>ExpiresByType image</param-name>
        <param-value>access plus 1 month</param-value>
    </init-param>
</filter>

该汽车租赁管理平台通过严谨的架构设计、完善的业务功能实现和多重安全防护措施,为传统汽车租赁行业提供了完整的数字化解决方案。系统具有良好的扩展性和维护性,为后续的功能升级和技术演进奠定了坚实基础。

本文关键词
JSPServlet在线汽车租赁预订系统源码解析

上下篇

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