ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

JavaEE毕业设计实战:从零搭建CRM系统

JavaEE毕业设计实战:从零搭建CRM系统 简介本资源是一套完整的基于JavaEE技术栈的毕业设计项目——客户关系管理系统CRM面向计算机专业本科生、Java初学者及Web开发入门者解决企业客户信息数字化管理需求。系统涵盖营销管理、客户管理、服务管理、统计报表与基础数据维护五大核心模块助力理解企业级Java Web应用的分层架构与业务闭环。压缩包共847个文件大小15.06MB包含156个HTML页面、140张PNG界面截图、132个CSS样式文件、119个JS交互脚本、74个Java源码与74个Class编译文件以及JSP视图、XML配置、SQL数据库脚本和完整项目报告文档结构清晰、功能可运行。已有181人学习下载读者可直接部署运行、对照源码理解MVC实现细节、分析Controller与Service层职责划分并参考配套报告完成毕业答辩材料准备。1. 为什么用 JavaEE 做毕业设计 CRM 系统不是“过时选择”而是稳扎稳打的工程训练场你可能在 GitHub 搜“JavaEE CRM”看到一堆 2015 年的仓库点开 README 就是 Tomcat 7 Struts2 Hibernate3 的组合心里一咯噔这玩意儿真能交毕业设计别急——恰恰是这套看似“老派”的技术栈成了高校毕设最扎实的练兵场它不靠框架黑盒自动帮你兜底每个请求怎么进、数据怎么查、事务怎么回滚、页面怎么渲染全得你亲手串起来。一个能跑通登录→客户录入→联系记录添加→统计报表导出全流程的 JavaEE CRM背后是 Servlet 生命周期理解、JDBC 连接池配置、JSP EL 表达式调试、web.xml 部署描述符写法、甚至 Tomcat 日志里ClassNotFoundException的逐行溯源能力。这不是复古情怀是把 Web 开发的“脏活累活”摊开给你练没有 Spring Boot 的SpringBootApplication一键启动你得自己配web.xml的servlet-mapping没有 MyBatis-Plus 的lambdaQuery()你得手写 SQL 拼接和PreparedStatement参数绑定。对本科生而言这种“慢速但可见”的构建过程比跑通一个 React 前端加 Node 后端更利于建立系统级认知——毕竟毕业设计要的不是炫技而是证明你能独立完成一个有边界、可验证、可调试、可交付的完整 Web 应用闭环。2. 从零搭起 JavaEE CRM 的最小可行环境VS Code 配置 Tomcat 本地部署2.1 VS Code 配置 JavaEE 开发环境告别 Eclipse 时代轻量但不失完整VS Code 本身不原生支持 JavaEE 全栈开发必须靠插件组合补足缺失链路。核心三件套缺一不可Extension Pack for Java微软官方提供基础 Java 语法校验、Maven 支持、调试器Tomcat for JavaRed Hat 出品直接在 VS Code 内启动/停止 Tomcat查看控制台日志无需切窗口Language Support for Java™ by Red Hat关键它让 JSP 文件能识别% %表达式、EL 语法如${user.name}否则 JSP 编辑器就是纯文本。提示安装完务必重启 VS Code且确保 JDK 版本为 Java 8 或 Java 11JavaEE 7/8 规范兼容性最佳。不要用 Java 17部分 Tomcat 9.x 对新版本反射 API 适配不全会导致ServletContainerInitializer加载失败。配置步骤分三步走在 VS Code 设置中搜索java.home指向你的 JDK 安装路径如C:\Program Files\Java\jdk-11.0.20打开命令面板CtrlShiftP输入Tomcat: Add Tomcat Server选择已下载的 Apache Tomcat 9.0.83推荐兼容 Java 11 且无已知 CVE解压目录右键项目根目录 →Deploy to Tomcat Server此时 VS Code 会自动生成.vscode/settings.json关键字段如下{ tomcat.javaHome: C:\\Program Files\\Java\\jdk-11.0.20, tomcat.servers: [ { name: Tomcat 9.0.83, path: D:\\apache-tomcat-9.0.83 } ] }逻辑说明tomcat.javaHome强制指定 JVM 运行时避免 VS Code 自动选错 JDKtomcat.servers是 VS Code 插件识别 Tomcat 实例的唯一依据路径必须精确到解压后的根目录含bin/和conf/子目录。若部署后访问http://localhost:8080报 404大概率是路径填错或 Tomcat 未真正启动——此时看 VS Code 底部状态栏是否显示Tomcat: Running而非Tomcat: Stopped。2.2 创建标准 JavaEE Web 项目结构手动建包拒绝 IDE 自动生成陷阱很多同学用 VS Code 的 Maven 插件新建maven-archetype-webapp结果生成的目录里src/main/webapp/WEB-INF/web.xml是空壳连servlet标签都没模板。毕设项目必须手建规范结构这是理解 JavaEE 部署契约的第一课crm-system/ ├── src/ │ ├── main/ │ │ ├── java/ # Java 类源码按包名分层 │ │ │ └── com/example/crm/ │ │ │ ├── servlet/ # 所有 Servlet 类 │ │ │ ├── dao/ # 数据访问对象JDBC 封装 │ │ │ ├── model/ # 实体类Customer, Contact 等 │ │ │ └── util/ # 工具类DBUtil, DateUtil │ │ ├── resources/ # 配置文件db.properties │ │ └── webapp/ # Web 资源根目录 │ │ ├── index.jsp │ │ ├── login.jsp │ │ ├── customer/ │ │ │ └── list.jsp │ │ └── WEB-INF/ │ │ ├── web.xml # 核心部署描述符必须 │ │ └── lib/ # 手动放入 jar 包见下文 │ └── test/ # 单元测试可选但建议加 └── pom.xml # Maven 构建配置参数说明web.xml是 JavaEE 的“宪法”所有 Servlet 映射、过滤器、监听器都由此定义WEB-INF/lib/下必须手动放入servlet-api.jarTomcat 自带勿重复引入、mysql-connector-java-8.0.33.jarMySQL 驱动、jstl-1.2.jarJSP 标签库用于c:forEach循环pom.xml中packaging必须设为war否则 Maven 不会打包成 WAR 文件packagingwar/packaging dependencies dependency groupIdjavax.servlet/groupId artifactIdjavax.servlet-api/artifactId version4.0.1/version scopeprovided/scope !-- 关键告诉 Maven 这个 jar 由 Tomcat 提供不打入 WAR -- /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.33/version /dependency /dependencies逻辑说明scopeprovided/scope是生死线。若漏写Maven 会把servlet-api.jar打进 WAR 的WEB-INF/lib/而 Tomcat 本身已加载同名类导致java.lang.LinkageError: loader constraint violation——这是毕设调试阶段最高频的崩溃原因。3. CRM 核心功能落地客户管理模块的三层实现Servlet JDBC JSP3.1 客户列表页从数据库查出数据安全传到 JSP 展示需求很朴素访问/customer/list显示所有客户姓名、电话、创建时间。但实现链路上每一步都藏着坑。Step 1DAO 层封装查询逻辑CustomerDao.javapublic class CustomerDao { public ListCustomer findAll() throws SQLException { String sql SELECT id, name, phone, email, create_time FROM customer ORDER BY create_time DESC; ListCustomer customers new ArrayList(); try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql); ResultSet rs ps.executeQuery()) { while (rs.next()) { Customer c new Customer(); c.setId(rs.getLong(id)); c.setName(rs.getString(name)); c.setPhone(rs.getString(phone)); c.setEmail(rs.getString(email)); c.setCreateTime(rs.getTimestamp(create_time)); customers.add(c); } } return customers; } }逻辑说明使用try-with-resources自动关闭连接、语句、结果集避免连接泄漏毕设答辩常被问“你怎么保证数据库连接不泄露”DBUtil.getConnection()必须是静态方法内部使用DriverManager.getConnection()或BasicDataSourceApache Commons DBCP不能每次 new Connection字段名严格匹配数据库列名create_time大小写敏感MySQL 默认小写别写成createTime。Step 2Servlet 接收请求并调用 DAOCustomerListServlet.javaWebServlet(/customer/list) public class CustomerListServlet extends HttpServlet { Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { CustomerDao dao new CustomerDao(); ListCustomer customers dao.findAll(); req.setAttribute(customers, customers); // 关键将数据存入 request 域 req.getRequestDispatcher(/customer/list.jsp).forward(req, resp); // 转发到 JSP } catch (SQLException e) { e.printStackTrace(); req.setAttribute(error, 查询客户列表失败 e.getMessage()); req.getRequestDispatcher(/error.jsp).forward(req, resp); } } }逻辑说明WebServlet(/customer/list)是 JavaEE 3.0 的注解式映射比web.xml更简洁但需确认 Tomcat 版本 ≥ 7.0req.setAttribute()是数据传递的唯一正道request域生命周期仅限本次请求比session更安全forward()是服务器端跳转URL 不变适合 MVC 中 Controller → View 流程Step 3JSP 页面渲染list.jsp% page contentTypetext/html;charsetUTF-8 languagejava % % taglib prefixc urihttp://java.sun.com/jsp/jstl/core % html headtitle客户列表/title/head body h2客户列表/h2 c:if test${empty customers} p暂无客户数据/p /c:if table border1 trthID/thth姓名/thth电话/thth邮箱/thth创建时间/th/tr c:forEach items${customers} varc tr td${c.id}/td td${c.name}/td td${c.phone}/td td${c.email}/td td${c.createTime}/td /tr /c:forEach /table /body /html参数说明% taglib ... %声明 JSTL 标签库c:forEach替代原始% for(...) { %脚本片段更安全、易读${customers}是 EL 表达式自动从request域取值无需request.getAttribute(customers)${empty customers}是 EL 判空比customers null || customers.size() 0更简洁4. 避坑指南JavaEE CRM 毕设开发中 4 个血泪高频问题4.1 现象访问/login返回 HTTP 404但web.xml里明明配了servlet-mapping原因web.xml中url-pattern的斜杠规则被忽略。例如写成url-patternlogin/url-pattern缺开头/实际匹配的是http://localhost:8080/login而 Tomcat 默认上下文路径是项目名如http://localhost:8080/crm-system/login导致 404。解决url-pattern必须以/开头且与浏览器地址栏路径严格一致。正确写法url-pattern/login/url-pattern对应访问http://localhost:8080/crm-system/login。4.2 现象JSP 页面中文乱码显示为??原因三个环节编码未统一① JSP 文件本身保存为 UTF-8②% page contentTypetext/html;charsetUTF-8 %声明③ Tomcat 的conf/server.xml中Connector标签未加URIEncodingUTF-8。解决在server.xml的Connector port8080 ... /标签内追加属性Connector port8080 protocolHTTP/1.1 connectionTimeout20000 redirectPort8443 URIEncodingUTF-8 /重启 Tomcat 生效。4.3 现象新增客户后数据库插入成功但页面跳转回列表页却看不到新数据原因Servlet 中resp.sendRedirect(/customer/list)用了重定向302导致浏览器发起新请求但新请求未重新查询数据库而是从缓存或旧 request 域取数据实际是空。解决必须用forward()而非sendRedirect()。重定向适用于表单提交后防刷新重复提交但需配合req.getSession().setAttribute()临时存提示信息而列表页展示必须实时查库所以新增后应forward到列表 Servlet由其重新执行findAll()。4.4 现象MySQL 8.0 连接报错Public Key Retrieval is not allowed原因MySQL 8.0 默认启用caching_sha2_password认证插件而mysql-connector-java8.0.33 以下版本不支持需显式允许公钥检索。解决在db.properties的 JDBC URL 后追加参数jdbc.urljdbc:mysql://localhost:3306/crm?useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue注意allowPublicKeyRetrievaltrue是临时方案生产环境应升级驱动或改用sha256_password插件。5. 毕设加分项用 Filter 实现登录拦截 用 JSTL 标签库做权限控制5.1 登录拦截 Filter保护/customer/*路径未登录者强制跳转只靠login.jsp和LoginServlet不够必须防止用户绕过登录直接访问http://localhost:8080/crm-system/customer/list。Filter 是 JavaEE 标准解决方案WebFilter(/customer/*) public class AuthFilter implements Filter { Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request (HttpServletRequest) req; HttpServletResponse response (HttpServletResponse) resp; // 检查 session 中是否有 user 对象 Object user request.getSession().getAttribute(currentUser); if (user null) { // 未登录重定向到登录页并保留原请求路径作为参数 String originalUrl request.getRequestURI(); response.sendRedirect(request.getContextPath() /login.jsp?redirect URLEncoder.encode(originalUrl, UTF-8)); return; } chain.doFilter(req, resp); // 放行 } }逻辑说明WebFilter(/customer/*)拦截所有/customer/开头的请求request.getSession().getAttribute(currentUser)是登录成功后LoginServlet存入 session 的用户对象URLEncoder.encode()对原始 URL 编码避免?等符号破坏跳转链接response.sendRedirect()是客户端跳转URL 变为/login.jsp?redirect%2Fcustomer%2Flist登录成功后可解析redirect参数跳回原页。5.2 JSTL 权限标签不同角色看到不同操作按钮CRM 系统常需区分管理员和普通员工。假设User实体有role字段admin 或 staff可在 JSP 中用c:if控制按钮显示c:if test${user.role admin} a href/customer/add[新增客户]/a a href/customer/delete?id${c.id}[删除]/a /c:if c:if test${user.role staff} a href/contact/add?customerId${c.id}[添加联系记录]/a /c:if参数说明${user.role}从 session 或 request 中取值user是登录后存入的User对象c:if标签比% if(...) { %更安全不暴露 Java 代码也避免脚本片段中引号嵌套混乱按钮链接中的?customerId${c.id}是典型 RESTful 风格传参c是c:forEach循环变量。5.3 毕设答辩必答技巧如何解释你选择 JavaEE 而非 Spring Boot别背“Spring Boot 太重”这种虚话。直接说三点硬核理由教学目标匹配课程要求掌握 Servlet 生命周期、JSP 编译原理、web.xml 部署契约这些是 JavaEE 规范基石Spring Boot 将其封装为黑盒调试可见性当NullPointerException发生在CustomerDao.findAll()我能直接断点到 JDBC 连接获取处看conn是否为 null而 Spring Boot 的Autowired注入失败堆栈深、定位难部署可控性WAR 包丢进 Tomcatwebapps/目录即运行无需java -jar、无需application.yml配置符合学校机房统一运维要求。我带过三届毕设学生用 Spring Boot 的80% 卡在Transactional不生效或RestController返回 JSON 时中文乱码而用 JavaEE 的问题都集中在web.xml配错或Class.forName()加载驱动失败——前者查文档就能解决后者是真刀真枪练出来的能力。希望帮到你。本文还有配套的精品资源点击获取
返回列表