JSP上机实习报告写作指南:从环境搭建到增删改查完整实现

发布时间:2026/10/15 4:17:18
JSP上机实习报告写作指南:从环境搭建到增删改查完整实现
简介这份JSP上机实习报告面向高校Java Web课程学习者尤其适合正在完成JSP开发技术实验、需要参考完整实验报告格式与代码实现的学生。报告围绕JSP基础语法、JavaBean封装、字符串安全转换及登录验证等典型上机题目展开涵盖从创建动态Web项目、页面输出计算到请求参数处理与页面跳转的完整流程可作为课程作业的对照模板与排错参考。资源包共1个doc文件大小约38KB内容以实验题目、实现过程、代码片段与心得总结为主结构清晰便于直接查阅与模仿练习。目前已有102人学习下载适合刚接触JSP、需要快速理解实验步骤与代码组织方式的初学者也可为教师批改或课程设计提供参考样例。1. 一份 JSP 上机实习报告到底该写什么从“能跑”到“能讲清楚”很多同学拿到“JSP 上机实习报告”这个任务时第一反应是打开 Word 就开始堆截图环境搭好了截一张页面能跑了截一张数据库连上了再截一张。结果交上去被导师一句“你这报告看不出你做了什么”打回来。问题不在态度在于没搞清楚这份报告的本质——它不是操作流水账而是一份能证明你理解了 JSP 请求响应链路、能独立完成一个最小 Web 应用的技术文档。JSP 上机实习报告的核心是围绕一个可运行的小型 Web 项目把环境搭建、页面开发、数据库交互、部署调试这条链路完整记录下来。它适合正在学 Java Web 课程的学生也适合刚转 Java 后端、需要用一个练手项目把 Servlet/JSP 体系串起来的开发者。报告写得好不好不看你用了多少框架而看你能否把“浏览器发一个请求到页面返回结果”这件事讲明白。下面我按实际做项目的顺序把这份报告该怎么写、代码该怎么放、参数该怎么调一层层拆开。2. 先定项目骨架用 JSP Servlet JDBC 搭一个最小可运行系统2.1 为什么选 JSP Servlet JDBC 而不是直接上框架常见做法是先用原生 JSP Servlet JDBC 把整个请求链路跑通再考虑要不要引入框架。原因很直接上机实习报告要展示的是你对 Web 基础的理解而不是你调框架 API 的熟练度。用原生方案你能清楚看到HttpServletRequest怎么拿参数、HttpServletResponse怎么输出、web.xml或注解怎么配映射、JDBC 怎么拿连接。这些在报告里都是可以写清楚的技术点。如果一上来就用 Spring Boot MyBatis报告很容易变成“我配了 application.yml然后就好了”导师看不到你的工作量也看不到你对底层机制的理解。所以我的建议是主体用 JSP Servlet JDBC把增删改查做完整报告里重点写清楚请求参数怎么流转、SQL 怎么执行、结果怎么回填到 JSP 页面。项目结构按标准 Web 应用来组织目录大致如下project-root/ ├── src/ │ └── main/ │ ├── java/ │ │ └── com/example/student/ │ │ ├── dao/ │ │ │ └── StudentDao.java │ │ ├── model/ │ │ │ └── Student.java │ │ └── servlet/ │ │ ├── StudentListServlet.java │ │ └── StudentAddServlet.java │ ├── resources/ │ │ └── db.properties │ └── webapp/ │ ├── WEB-INF/ │ │ └── web.xml │ ├── index.jsp │ └── student/ │ ├── list.jsp │ └── add.jsp └── pom.xml这个结构里model放实体类dao放数据库操作servlet放控制器webapp放 JSP 页面。报告里要把这个结构画出来用文字描述即可并说明每一层职责。导师一看就知道你不是把所有代码塞在一个 JSP 里。2.2 数据库表设计与 JDBC 连接配置先建一张学生表字段不用多够演示增删改查就行CREATE TABLE student ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL, age INT, major VARCHAR(100), create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP );然后在db.properties里写连接参数jdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/practice_db?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8 jdbc.usernameroot jdbc.passwordyour_password这里有几个参数必须说清楚。serverTimezoneAsia/Shanghai不加MySQL 8 会报时区错误characterEncodingutf8不加中文会乱码useSSLfalse在本地练习环境可以关掉避免证书警告。报告里要把这些参数的含义写出来这是体现你踩过坑的地方。写一个工具类加载配置并获取连接public class DBUtil { private static String url; private static String username; private static String password; static { try (InputStream in DBUtil.class.getClassLoader() .getResourceAsStream(db.properties)) { Properties props new Properties(); props.load(in); Class.forName(props.getProperty(jdbc.driver)); url props.getProperty(jdbc.url); username props.getProperty(jdbc.username); password props.getProperty(jdbc.password); } catch (Exception e) { throw new RuntimeException(数据库配置加载失败, e); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(url, username, password); } }这段代码的逻辑是类加载时读取配置文件注册驱动把连接参数存到静态变量。之后每次调用getConnection()就返回一个新连接。注意这里没有用连接池上机练习够用但报告里可以提一句“生产环境应使用连接池”体现你知道边界。2.3 用 Servlet 处理请求用 JSP 做视图渲染先写一个列表查询的 ServletWebServlet(/student/list) public class StudentListServlet extends HttpServlet { private StudentDao studentDao new StudentDao(); Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ListStudent students studentDao.findAll(); req.setAttribute(students, students); req.getRequestDispatcher(/student/list.jsp).forward(req, resp); } }逻辑说明doGet里调用 DAO 查出所有学生把结果放到request作用域然后转发到list.jsp。这里用forward而不是redirect因为需要把数据带到页面。参数方面WebServlet(/student/list)定义了访问路径浏览器访问http://localhost:8080/项目名/student/list就会触发这个 Servlet。对应的list.jsp用 JSTL 遍历展示% page contentTypetext/html;charsetUTF-8 languagejava % % taglib prefixc urihttp://java.sun.com/jsp/jstl/core % html headtitle学生列表/title/head body table border1 trthID/thth姓名/thth年龄/thth专业/th/tr c:forEach items${students} vars tr td${s.id}/td td${s.name}/td td${s.age}/td td${s.major}/td /tr /c:forEach /table /body /html这里% taglib %引入 JSTL 标签库c:forEach遍历students集合。注意${s.id}这种 EL 表达式依赖实体类有对应的 getter 方法。报告里要写清楚JSP 页面不写 Java 代码只负责展示业务逻辑在 Servlet 和 DAO 里。3. 把增删改查写完整DAO 层与页面交互的四个关键动作3.1 查询与新增从表单提交到数据库插入新增功能需要两个部分一个展示表单的 JSP一个处理提交的 Servlet。先看表单form action${pageContext.request.contextPath}/student/add methodpost 姓名input typetext namenamebr 年龄input typenumber nameagebr 专业input typetext namemajorbr input typesubmit value提交 /formaction里用${pageContext.request.contextPath}动态获取项目上下文路径避免项目名改了之后路径失效。methodpost用于提交数据中文参数需要在 Servlet 里设置编码。对应的 ServletWebServlet(/student/add) public class StudentAddServlet extends HttpServlet { private StudentDao studentDao new StudentDao(); Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding(UTF-8); String name req.getParameter(name); int age Integer.parseInt(req.getParameter(age)); String major req.getParameter(major); Student student new Student(name, age, major); studentDao.insert(student); resp.sendRedirect(req.getContextPath() /student/list); } }关键点req.setCharacterEncoding(UTF-8)必须在getParameter之前调用否则中文会乱码。插入完成后用sendRedirect重定向到列表页避免刷新页面重复提交。这是典型的 PRGPost-Redirect-Get模式报告里可以作为一个技术点写出来。DAO 的插入方法public void insert(Student student) { String sql INSERT INTO student(name, age, major) VALUES(?, ?, ?); try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, student.getName()); ps.setInt(2, student.getAge()); ps.setString(3, student.getMajor()); ps.executeUpdate(); } catch (SQLException e) { throw new RuntimeException(插入学生失败, e); } }用PreparedStatement而不是Statement一是防止 SQL 注入二是参数设置更清晰。try-with-resources保证连接和语句自动关闭。报告里要说明这里没有手动close()是因为try-with-resources会自动处理。3.2 修改与删除基于 ID 的定位与参数传递删除功能通过 URL 参数传递 IDWebServlet(/student/delete) public class StudentDeleteServlet extends HttpServlet { private StudentDao studentDao new StudentDao(); Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { int id Integer.parseInt(req.getParameter(id)); studentDao.deleteById(id); resp.sendRedirect(req.getContextPath() /student/list); } }列表页每行加一个删除链接tda href${pageContext.request.contextPath}/student/delete?id${s.id}删除/a/td修改功能稍微复杂一点需要先根据 ID 查出原数据回填到表单再提交更新。查询单个学生的 ServletWebServlet(/student/edit) public class StudentEditServlet extends HttpServlet { private StudentDao studentDao new StudentDao(); Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { int id Integer.parseInt(req.getParameter(id)); Student student studentDao.findById(id); req.setAttribute(student, student); req.getRequestDispatcher(/student/edit.jsp).forward(req, resp); } }edit.jsp表单里把原值填进去form action${pageContext.request.contextPath}/student/update methodpost input typehidden nameid value${student.id} 姓名input typetext namename value${student.name}br 年龄input typenumber nameage value${student.age}br 专业input typetext namemajor value${student.major}br input typesubmit value更新 /form更新 Servlet 里拿到id和修改后的字段调用 DAO 的update方法。这里要注意id用隐藏域传递不能放在 URL 里因为更新是 POST 请求。报告里可以对比删除用 GET、更新用 POST 的区别说明为什么这样设计。3.3 分页查询用 LIMIT 和 COUNT 把数据量控制住数据一多列表页会很长。加一个简单分页public ListStudent findByPage(int page, int pageSize) { String sql SELECT * FROM student LIMIT ?, ?; ListStudent list new ArrayList(); try (Connection conn DBUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setInt(1, (page - 1) * pageSize); ps.setInt(2, pageSize); ResultSet rs ps.executeQuery(); while (rs.next()) { list.add(mapRow(rs)); } } catch (SQLException e) { throw new RuntimeException(分页查询失败, e); } return list; }LIMIT的第一个参数是偏移量计算公式是(当前页 - 1) * 每页条数。第二个参数是每页条数。还需要一个统计总数的 SQLSELECT COUNT(*) FROM studentServlet 里算出总页数把当前页、总页数、数据列表一起放到 request 里JSP 页面渲染分页链接。报告里要写清楚分页不是必须的但加上去能体现你对数据量增长的考虑是加分项。3.4 用过滤器统一处理编码和登录校验每个 Servlet 都写setCharacterEncoding很啰嗦用一个过滤器统一处理WebFilter(/*) public class EncodingFilter implements Filter { Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { req.setCharacterEncoding(UTF-8); resp.setContentType(text/html;charsetUTF-8); chain.doFilter(req, resp); } }WebFilter(/*)表示拦截所有请求。这样就不用在每个 Servlet 里重复设置编码了。报告里可以顺带提一句过滤器还可以做登录校验判断 session 里有没有用户信息没有就跳转到登录页。这是 JSP 实习报告里常见的扩展点。4. 避坑与排查JSP 上机实习报告里最容易翻车的五个地方4.1 中文乱码现象是页面显示问号原因是编码链路没统一现象表单提交中文数据库里存进去变成???或者页面显示乱码。原因编码问题涉及三个环节——JSP 页面编码、请求编码、数据库编码。任何一个环节不是 UTF-8 都会出问题。解决JSP 页面头部写% page contentTypetext/html;charsetUTF-8 %Servlet 里req.setCharacterEncoding(UTF-8)放在第一行数据库连接 URL 加characterEncodingutf8建表时字段用utf8mb4。四个地方都对齐乱码基本消失。4.2 404 错误现象是访问路径报找不到原因是映射配错了现象浏览器访问/student/list报 404。原因可能是WebServlet的路径写错或者web.xml里url-pattern和实际访问路径不一致也可能是项目部署路径context path没算进去。解决先看 Tomcat 启动日志里有没有注册这个 Servlet再确认访问 URL 是http://localhost:8080/项目名/student/list项目名不能漏如果用web.xml配置检查servlet-mapping的url-pattern是否和访问路径匹配。报告里可以把启动日志截图放上去说明你是怎么定位的。4.3 数据库连接失败现象是ClassNotFoundException或Access denied原因是驱动或密码不对现象启动时报ClassNotFoundException: com.mysql.cj.jdbc.Driver或者Access denied for user。原因第一种是 MySQL 驱动 jar 没放到WEB-INF/lib下第二种是用户名密码写错或者数据库没启动。解决确认pom.xml里有mysql-connector-java依赖或者手动把 jar 放到WEB-INF/lib检查db.properties里的用户名密码用命令行mysql -u root -p确认能登录。报告里要写清楚驱动版本要和 MySQL 版本匹配MySQL 8 用com.mysql.cj.jdbc.DriverMySQL 5 用com.mysql.jdbc.Driver。4.4 JSTL 标签不生效现象是c:forEach原样输出原因是标签库没引入或 jar 缺失现象页面直接把c:forEach当文本显示出来。原因要么没写% taglib %指令要么缺少jstl.jar和standard.jar。解决JSP 页面顶部加% taglib prefixc urihttp://java.sun.com/jsp/jstl/core %确认项目依赖里有 JSTL 实现。如果用的是 Maven加javax.servlet:jstl依赖。报告里可以说明JSTL 不是 JSP 内置的需要额外引入。4.5 刷新导致重复提交现象是刷新页面又插入一条原因是没用重定向现象新增完成后按 F5数据库里多了一条重复数据。原因表单提交后直接forward到结果页浏览器地址栏还是提交前的 URL刷新就会重新提交。解决提交处理完成后用resp.sendRedirect()重定向到列表页。这样浏览器地址栏变成列表页 URL刷新不会重复提交。这是 PRG 模式的核心报告里要作为一个独立技术点写出来。5. 报告怎么写才像做过截图、代码和问题记录的取舍5.1 截图不是越多越好关键页面配文字说明很多报告通篇截图导师翻半天不知道重点在哪。我的习惯是每个功能模块配一张关键截图截图下面用两三句话说明“这个页面做了什么、数据从哪来、点了之后发生什么”。比如列表页截图下面写“该页面由StudentListServlet转发而来数据来自student表通过 JSTL 遍历展示。”这样导师一看就知道你理解整个链路。截图要包含浏览器地址栏证明是你自己跑起来的。数据库截图要包含表结构和数据证明数据真的存进去了。不要只截代码代码可以用文字贴截图留给运行效果。5.2 代码片段要挑核心的贴不要整文件复制报告里贴代码挑每个功能最核心的十几行。比如 DAO 的查询方法、Servlet 的doGet、JSP 的遍历逻辑。整文件复制会让报告变得很长导师也找不到重点。贴完代码后面加一段说明这段代码解决什么问题、关键参数是什么、如果改需求要动哪里。代码块要标注语言Java 代码用javaSQL 用sqlJSP 用jsp。这样在 Word 里粘贴也能保持格式清晰。5.3 问题记录比功能描述更能体现水平报告里专门留一节写“遇到的问题和解决过程”。比如“中文乱码问题现象是……原因是……解决是……”。这种记录比单纯描述功能更有说服力因为它证明你真的动手了而且有能力定位问题。导师看报告时往往最关注这一部分。问题记录按“现象 → 原因 → 解决 → 验证”四步写。验证就是改完之后怎么确认问题消失了比如“重新提交表单数据库里中文显示正常页面刷新无乱码”。5.4 部署说明要写清楚让别人能复现报告最后附一段部署说明用什么 JDK 版本、什么 Tomcat 版本、什么 MySQL 版本、数据库脚本在哪、怎么导入项目、怎么启动。这样导师或者同学拿到你的报告能照着步骤把项目跑起来。部署说明不用长一个表格列清楚环境版本一个代码块放启动命令就够了。环境项版本要求JDK1.8 或以上Tomcat8.5 或以上MySQL5.7 或 8.0IDE任意支持 Java Web 的 IDE启动步骤用文字写先执行student.sql建表再修改db.properties里的数据库密码然后把项目部署到 Tomcat访问http://localhost:8080/项目名/student/list。5.5 一个让报告加分的技巧把请求链路画成文字时序不用画图用文字把一次请求的完整路径写出来。比如“新增学生”的链路浏览器访问/student/add.jsp填写表单点击提交。表单 POST 到/student/addTomcat 根据WebServlet找到StudentAddServlet。doPost方法先设置编码再通过req.getParameter拿到三个字段。封装成Student对象调用StudentDao.insert。DAO 通过DBUtil.getConnection拿到连接执行INSERTSQL。插入成功后resp.sendRedirect让浏览器重新访问/student/list。StudentListServlet查询所有数据转发到list.jsp渲染。这段文字放在报告里导师一眼就能看出你清楚整个请求响应过程。这也是我每次做 Web 项目都会先写一遍的东西写清楚了再动手代码不容易乱。希望帮到你。本文还有配套的精品资源点击获取