简介:这份资源是面向计算机专业学生与Java Web初学者的一份完整毕业设计文档,主题为基于JSP的在线家政网设计与实现,可用于课程设计、毕业设计参考或Web开发入门学习。压缩包内共1个docx文件,约1.02MB,内容为完整的论文文档,涵盖摘要、目录、可行性分析、系统分析、数据库设计及功能模块实现等章节。文档围绕B/S模式、JSP技术、SQL Server 2008数据库与MyEclipse开发平台展开,详细阐述了家政信息预约、家教预约、在线求职及个人后台管理等模块的结构化分析与设计过程,并给出概念结构、逻辑结构与物理结构三阶段的数据库设计思路。目前已有126人学习下载,适合需要参考完整项目文档结构、了解JSP网站开发流程或撰写同类毕业设计的读者,可帮助快速理清系统功能模块划分与论文写作框架。
1. 从一份 .docx 标题说起:JSP 家政网到底在做什么
如果你在网上搜到「基于jsp的在线家政网设计与实现.docx」,大概率是两种情况:一是课程设计或毕业设计选题,二是想拿一套现成的 JSP 项目改改交差。不管哪种,核心问题都一样——这套东西到底包含哪些模块、用什么技术栈、能不能在本地跑起来、数据库怎么建。我见过太多人卡在第一步:文档里写得天花乱坠,真动手时连 MyEclipse 里怎么配 SQL Server 驱动都搞不定。
在线家政网的本质是一个「服务撮合 + 订单管理」的信息系统。用户端要能浏览保洁、月嫂、维修等家政服务,下单预约;管理端要能审核服务人员、派单、查看订单状态。JSP 在这里扮演的是服务端页面渲染角色,配合 Servlet 或 JavaBean 处理业务逻辑,SQL Server 存数据。这套组合在 2024 年看确实老,但它的价值在于:结构清晰、资料多、答辩好讲。适合计算机专业学生、刚入行的 Java Web 开发者,以及需要快速交付一个可演示系统的场景。下面我按实际做项目的顺序,把选型、建库、编码、排错、进阶一条线讲透。
2. 技术选型与开发环境:为什么是 JSP + MyEclipse + SQL Server
2.1 这套组合的合理性在哪
先说清楚一件事:JSP 不是不能用,而是要看场景。在线家政网这类系统,页面数量在 20 到 40 个之间,业务逻辑以增删改查为主,并发要求不高。JSP 的优势是「页面即服务」,不需要前后端分离那套构建工具链,一个 Tomcat 加一个 IDE 就能跑。MyEclipse 虽然笨重,但它对 JSP 的代码提示、Tomcat 集成、数据库浏览器做得比较顺手,尤其适合不熟悉 Maven 的人。SQL Server 在 Windows 环境下安装配置比 MySQL 少踩一些编码坑,企业管理器可视化建表也直观。
选型时真正要权衡的是三件事:第一,你的机器能不能装 SQL Server(内存至少 4G,最好 8G);第二,Tomcat 版本和 JDK 版本要匹配,JSP 项目一般用 JDK 8 + Tomcat 8 或 9;第三,SQL Server 驱动包版本要和数据库版本对应,2008 R2 用 sqljdbc4.jar,2012 以上用 sqljdbc42.jar。这些版本对不上,后面报错能让你查半天。
2.2 环境搭建的具体步骤
先装 JDK,配好 JAVA_HOME 和 Path。然后装 Tomcat,解压版就行,不用安装版。MyEclipse 安装时注意选择工作空间路径不要有中文和空格。SQL Server 安装时实例名记清楚,默认是 MSSQLSERVER,混合认证模式要开启,sa 账号密码设一个你记得住的。
# 验证 JDK 安装 java -version # 输出应为 java version "1.8.0_xxx" # 验证 Tomcat 能否启动 cd /path/to/tomcat/bin # Windows 下执行 startup.bat,Linux/Mac 下执行 startup.sh # 浏览器访问 http://localhost:8080 看到 Tomcat 首页即成功上面命令的作用是确认基础环境没问题。java -version看版本,如果显示 1.7 或更低,JSP 页面里的 EL 表达式可能不支持,建议换 1.8。Tomcat 启动后如果 8080 端口被占用,改conf/server.xml里的 Connector port。
2.3 数据库连接配置与驱动放置
在 MyEclipse 里新建 Web Project 后,把 sqljdbc4.jar 复制到WebRoot/WEB-INF/lib目录下。然后写一个数据库连接工具类,我一般叫DBUtil.java。
// DBUtil.java 数据库连接工具类 import java.sql.*; public class DBUtil { // 数据库驱动,注意版本对应 private static final String DRIVER = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; // 连接地址,databaseName 换成你的库名 private static final String URL = "jdbc:sqlserver://localhost:1433;databaseName=HousekeepingDB;encrypt=false"; private static final String USER = "sa"; private static final String PASSWORD = "你的密码"; public static Connection getConnection() { Connection conn = null; try { Class.forName(DRIVER); conn = DriverManager.getConnection(URL, USER, PASSWORD); } catch (Exception e) { e.printStackTrace(); // 生产环境应写日志 } return conn; } public static void close(Connection conn, Statement stmt, ResultSet rs) { try { if (rs != null) rs.close(); } catch (Exception e) {} try { if (stmt != null) stmt.close(); } catch (Exception e) {} try { if (conn != null) conn.close(); } catch (Exception e) {} } }这段代码的关键参数有三个:DRIVER必须是com.microsoft.sqlserver.jdbc.SQLServerDriver,写错一个字母就报 ClassNotFound;URL里的encrypt=false在 SQL Server 2008 R2 上必须加,否则连接被拒;databaseName要和你在数据库里建的库名完全一致。close方法按 ResultSet、Statement、Connection 的顺序关闭,反了会报错。很多人图省事不关连接,跑几次就提示「连接池已满」,这是血泪经验。
3. 数据库设计与建表:家政网的核心表结构
3.1 先想清楚业务再动手建表
家政网的数据模型不复杂,但有几个地方容易设计错。用户表和服务人员表要分开,因为服务人员有审核状态、技能标签、接单数量这些额外字段。订单表要同时关联用户和服务人员,还要记录服务类型、预约时间、订单状态。服务类型表单独建,方便后台增删改。评价表关联订单,一个订单只能评一次。
我一般会建六张核心表:users(普通用户)、staff(服务人员)、service_type(服务分类)、orders(订单)、comments(评价)、admin(管理员)。下面给出关键表的建表语句。
-- 创建数据库 CREATE DATABASE HousekeepingDB; GO USE HousekeepingDB; GO -- 用户表 CREATE TABLE users ( user_id INT IDENTITY(1,1) PRIMARY KEY, username NVARCHAR(50) NOT NULL UNIQUE, password NVARCHAR(50) NOT NULL, phone NVARCHAR(20), address NVARCHAR(200), reg_time DATETIME DEFAULT GETDATE() ); -- 服务人员表 CREATE TABLE staff ( staff_id INT IDENTITY(1,1) PRIMARY KEY, staff_name NVARCHAR(50) NOT NULL, phone NVARCHAR(20), skill NVARCHAR(100), -- 技能标签,如保洁、月嫂 status INT DEFAULT 0, -- 0待审核 1已通过 2已拒绝 order_count INT DEFAULT 0 -- 接单数,用于排序 ); -- 订单表 CREATE TABLE orders ( order_id INT IDENTITY(1,1) PRIMARY KEY, user_id INT FOREIGN KEY REFERENCES users(user_id), staff_id INT FOREIGN KEY REFERENCES staff(staff_id), service_id INT, order_time DATETIME DEFAULT GETDATE(), appoint_time DATETIME, -- 预约上门时间 status INT DEFAULT 0, -- 0待接单 1已接单 2已完成 3已取消 remark NVARCHAR(300) );建表时注意NVARCHAR而不是VARCHAR,因为中文姓名和地址用 VARCHAR 可能乱码。IDENTITY(1,1)是自增主键,从 1 开始每次加 1。GETDATE()是 SQL Server 的当前时间函数。外键约束建议加上,虽然插入数据时麻烦一点,但能防止脏数据。
3.2 插入测试数据与验证
建完表要插几条测试数据,不然页面全是空的没法调试。
-- 插入管理员 INSERT INTO admin (admin_name, password) VALUES ('admin', '123456'); -- 插入服务分类 INSERT INTO service_type (type_name, price) VALUES ('日常保洁', 80); INSERT INTO service_type (type_name, price) VALUES ('月嫂服务', 300); INSERT INTO service_type (type_name, price) VALUES ('家电维修', 120); -- 插入测试用户 INSERT INTO users (username, password, phone, address) VALUES ('zhangsan', '123456', '13800001111', '朝阳区某小区');插入后执行SELECT * FROM users;确认数据在。如果中文显示问号,检查数据库排序规则是不是Chinese_PRC_CI_AS,不是的话建库时就要指定。
3.3 分页查询的 SQL 写法
家政网的服务列表、订单列表都需要分页。SQL Server 2008 R2 不支持LIMIT,用ROW_NUMBER()实现。
-- 查询第 2 页,每页 10 条 SELECT * FROM ( SELECT ROW_NUMBER() OVER (ORDER BY staff_id DESC) AS row_num, * FROM staff WHERE status = 1 ) AS t WHERE t.row_num BETWEEN 11 AND 20;ROW_NUMBER() OVER (ORDER BY ...)生成行号,外层再筛选区间。BETWEEN 11 AND 20对应第二页。页码和每页条数在 Java 里算好传进来,不要拼字符串,用 PreparedStatement 防注入。
4. 核心功能模块的 JSP 实现:从登录到下单
4.1 登录模块与 Session 管理
登录是第一个要跑通的功能。用户提交表单到loginServlet,Servlet 查数据库验证,成功则把用户信息存入 Session,跳转首页。
// LoginServlet.java 核心逻辑 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); String username = request.getParameter("username"); String password = request.getParameter("password"); String sql = "SELECT * FROM users WHERE username=? AND password=?"; try (Connection conn = DBUtil.getConnection(); PreparedStatement ps = conn.prepareStatement(sql)) { ps.setString(1, username); ps.setString(2, password); ResultSet rs = ps.executeQuery(); if (rs.next()) { HttpSession session = request.getSession(); session.setAttribute("userId", rs.getInt("user_id")); session.setAttribute("userName", rs.getString("username")); response.sendRedirect("index.jsp"); } else { request.setAttribute("msg", "用户名或密码错误"); request.getRequestDispatcher("login.jsp").forward(request, response); } } catch (Exception e) { e.printStackTrace(); } }request.setCharacterEncoding("UTF-8")必须放在取参数之前,否则中文用户名乱码。PreparedStatement用?占位,setString按顺序填,这是防 SQL 注入的标准做法。Session 里存userId而不是整个用户对象,减少内存占用。登录失败用forward而不是redirect,这样request里的提示信息能带到页面。
4.2 服务列表展示与图片坐标定位
服务列表页要展示服务图片、名称、价格。JSP 里用 JSTL 遍历。
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <table> <c:forEach items="${serviceList}" var="s"> <tr> <td><img src="images/${s.image}" width="120" height="90"/></td> <td>${s.typeName}</td> <td>${s.price} 元/次</td> <td><a href="order.jsp?serviceId=${s.typeId}">预约</a></td> </tr> </c:forEach> </table>这里有个热搜词提到「jsp图片如何对坐标定位」,实际场景是首页轮播图或服务分类图标需要点击不同区域跳转不同链接。做法是用<map>和<area>标签。
<img src="images/banner.jpg" usemap="#bannerMap" width="800" height="300"/> <map name="bannerMap"> <area shape="rect" coords="0,0,260,300" href="cleanList.jsp" alt="保洁"/> <area shape="rect" coords="260,0,520,300" href="nannyList.jsp" alt="月嫂"/> <area shape="rect" coords="520,0,800,300" href="repairList.jsp" alt="维修"/> </map>coords四个数字分别是左上角 x、y 和右下角 x、y。shape="rect"表示矩形区域。这个方案在 PC 端没问题,移动端要改成响应式布局,否则坐标对不上。
4.3 下单流程与事务处理
下单要同时往orders表插记录、更新staff表的接单数。这两个操作要么都成功,要么都回滚。
// OrderServlet.java 下单核心 Connection conn = null; try { conn = DBUtil.getConnection(); conn.setAutoCommit(false); // 开启事务 String sql1 = "INSERT INTO orders (user_id, staff_id, service_id, appoint_time, status) VALUES (?,?,?,?,0)"; PreparedStatement ps1 = conn.prepareStatement(sql1); ps1.setInt(1, userId); ps1.setInt(2, staffId); ps1.setInt(3, serviceId); ps1.setTimestamp(4, new Timestamp(appointTime.getTime())); ps1.executeUpdate(); String sql2 = "UPDATE staff SET order_count = order_count + 1 WHERE staff_id = ?"; PreparedStatement ps2 = conn.prepareStatement(sql2); ps2.setInt(1, staffId); ps2.executeUpdate(); conn.commit(); // 提交事务 } catch (Exception e) { if (conn != null) conn.rollback(); // 回滚 e.printStackTrace(); } finally { if (conn != null) { conn.setAutoCommit(true); conn.close(); } }setAutoCommit(false)关闭自动提交,两条 SQL 都执行成功才commit(),任何一条抛异常就rollback()。setTimestamp处理日期类型,避免字符串拼接导致的格式错误。热搜里有人搜「sql server conversion failed when converting date and/or time」,多半就是日期字符串格式和数据库不匹配,用Timestamp对象传参最稳。
5. 避坑与排查:JSP 家政网开发中最容易翻车的 5 个点
5.1 中文乱码:现象是页面显示问号或方块
现象:登录后欢迎语变成「??」,或者数据库里存的中文查出来是乱码。原因有三个层面:JSP 页面编码、Servlet 请求编码、数据库排序规则。解决:JSP 文件头加<%@ page contentType="text/html;charset=UTF-8" %>,Servlet 里request.setCharacterEncoding("UTF-8")和response.setContentType("text/html;charset=UTF-8")都要写,数据库建库时排序规则选Chinese_PRC_CI_AS。三个地方缺一个都会翻车。
5.2 数据库连接报错:端口或驱动不对
现象:启动 Tomcat 后访问页面,控制台报Connection refused或ClassNotFoundException。原因:SQL Server 的 TCP/IP 协议没启用,或者 1433 端口被防火墙拦了,或者驱动 jar 没放进WEB-INF/lib。解决:打开 SQL Server 配置管理器,启用 TCP/IP,重启服务;检查防火墙入站规则;确认sqljdbc4.jar在 lib 目录且 Build Path 里也有。
5.3 JSP 页面修改后不生效
现象:改了 JSP 代码,刷新浏览器还是旧内容。原因:Tomcat 缓存了编译后的 Servlet,或者浏览器缓存。解决:清 Tomcat 的work目录,浏览器按 Ctrl+F5 强制刷新。MyEclipse 里可以配置自动重载,但有时候不灵,手动清最靠谱。
5.4 订单状态更新失败但页面提示成功
现象:用户点击「完成订单」,页面跳转成功,但数据库里 status 还是 1。原因:Servlet 里执行了 update 但没检查返回值,或者事务没提交。解决:executeUpdate()返回影响行数,判断是否大于 0;如果用事务,确认commit()被调用了。这个坑很隐蔽,因为页面不报错。
5.5 SQL Server 2008 R2 安装后 sa 登录失败
现象:用 sa 账号连不上,提示「登录失败」。原因:安装时选了 Windows 认证模式,没启用混合认证。解决:用 Windows 认证登录后,在服务器属性里改成「SQL Server 和 Windows 身份验证模式」,然后重启服务,再启用 sa 账号并设密码。热搜里「sql server 2008 r2下载」和「sql server安装」的人多半会碰到这个。
6. 进阶技巧:用过滤器统一编码和登录校验
6.1 编码过滤器:一次配置全局生效
每个 Servlet 都写setCharacterEncoding太啰嗦,用 Filter 统一处理。
// EncodingFilter.java public class EncodingFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); chain.doFilter(request, response); // 放行 } public void init(FilterConfig config) {} public void destroy() {} }在web.xml里配置拦截所有请求。
<filter> <filter-name>EncodingFilter</filter-name> <filter-class>com.housekeeping.filter.EncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>EncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>url-pattern写/*表示所有请求都过这个过滤器。chain.doFilter是放行到下一个过滤器或目标资源,不写这行请求就断了。
6.2 登录校验过滤器:防止未登录直接访问内页
// LoginFilter.java 核心判断 HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; String uri = request.getRequestURI(); // 放行登录页、注册页、静态资源 if (uri.contains("login.jsp") || uri.contains("register.jsp") || uri.contains("loginServlet") || uri.contains(".css") || uri.contains(".js")) { chain.doFilter(req, resp); return; } // 检查 Session if (request.getSession().getAttribute("userId") == null) { response.sendRedirect(request.getContextPath() + "/login.jsp"); } else { chain.doFilter(req, resp); }getRequestURI()拿到当前请求路径,白名单里的直接放行。getContextPath()拿到项目名,避免硬编码路径导致部署后 404。这个过滤器能挡住 90% 的越权访问,但注意不要拦截登录接口本身,否则死循环。
6.3 验证方法:用 Postman 或浏览器开发者工具
改完过滤器后怎么确认生效?打开浏览器 F12,看 Network 面板。未登录状态下直接访问orderList.jsp,应该看到 302 跳转到login.jsp。如果返回 200 且内容是订单列表,说明过滤器没起作用,检查web.xml里 filter-mapping 的顺序,encoding 过滤器要在 login 过滤器之前。
6.4 一个我踩过的坑
有次部署到另一台机器,登录后一直跳回登录页。查了两小时才发现那台机器的 Tomcat 配置了sessionCookiePath,导致 JSESSIONID 写不进去。后来在context.xml里加sessionCookiePath="/"才解决。这件事让我养成习惯:换环境先测 Session 是否正常,别急着调业务代码。
做这类 JSP 项目,最怕的不是技术难,而是环境问题伪装成代码问题。我的习惯是每换一台机器,先跑一个最小登录 Demo,确认 JDK、Tomcat、数据库、驱动四者连通,再往上堆功能。希望帮到你。
本文还有配套的精品资源,点击获取