Servlet+JSP学生管理系统实战:从404/500错误到Tomcat底层原理
发布时间:2026/10/1 22:29:55来源:尧图网络
1. 这不是又一个“Hello World”为什么今天还要手写ServletJSP学生管理系统你点开这个标题大概率是正在赶Java Web课设、毕业设计或者被公司老项目临时拉去维护一段十年前的代码。别急着关页面——我带过三届计算机专业实训每年都有至少20个学生在“基于Servlet、JSP的学生管理系统”这个题目上卡在同一个地方不是不会写增删改查而是写完发现页面乱码、表单提交404、跳转后session丢失、JSP里EL表达式不生效……最后交上去的系统首页能显示但点击“添加学生”就报500后台日志里全是java.lang.ClassNotFoundException: org.apache.jsp.index_jsp这种让人头皮发麻的错误。这恰恰说明ServletJSP这套技术栈远没有过时它是一把“解剖刀”能让你真正看清Web应用底层运行逻辑。你看那些Spring Boot项目自动配置再智能一旦Tomcat启动失败、Filter链执行异常、JSP编译出错最终还是要回到web.xml怎么配、servlet-mapping路径是否正确、jsp-config里page-encoding设没设这些基础问题上。我去年帮一家做教务系统的公司排查线上故障问题根源就是他们用Maven打包时漏掉了/WEB-INF/lib下的jasper.jar导致JSP无法编译——而这个jar包在Eclipse里新建Dynamic Web Project时是默认勾选的但在IntelliJ IDEA里却需要手动添加。所以这个项目的价值从来不是“做个能用的系统”而是建立一套完整的、可验证的Web容器认知模型HTTP请求如何被Servlet接收、如何解析参数、如何转发给JSP渲染、JSP又如何被Tomcat编译成Servlet类、最终字节码如何被JVM加载执行。整个链条里任何一个环节出错都会表现为前端一个看似简单的404或500。而源码的价值就在于它把所有隐含的约定和默认行为都摊开给你看——比如为什么% page contentTypetext/html;charsetUTF-8 %必须写在JSP第一行因为Tomcat的Jasper引擎在解析JSP时会从头扫描直到遇到第一个page指令再据此设置响应头和字符集如果写在HTML标签后面前面的空白字符就会被当成静态文本输出导致Content-Type头已发送再设置就无效了。你不需要记住所有API但必须理解HttpServletRequest里的getParameter()和getAttribute()根本不是一回事RequestDispatcher.forward()是服务器端跳转URL不变而response.sendRedirect()是客户端重定向URL会变session.setAttribute()存的是对象引用不是深拷贝所以千万别把ArrayList直接塞进去然后在另一个Servlet里add()——我见过太多人因此出现并发修改异常。这些细节不是文档里一句话能讲清的得在真实调试中踩坑、看日志、打断点才能刻进肌肉记忆。2. 架构设计与技术选型为什么坚持不用Spring Boot很多人看到标题第一反应是“都2024年了还写Servlet用Spring Boot三行代码搞定的事干嘛自找麻烦”这个问题问得特别好答案也很实在因为Spring Boot帮你屏蔽了太多东西反而让你看不见Web容器的本质。就像学开车先上自动驾驶的特斯拉你永远不知道油门、离合、档位之间的配合逻辑。而ServletJSP就是那台化油器的老捷达——零件全露在外面哪个螺丝松了、哪根管路堵了你一眼就能看见。我们这个学生管理系统的架构严格遵循Java EE规范的分层思想但刻意去掉所有框架封装表现层Presentation Layer纯JSP JSTL EL表达式。不写一行JavaScript操作DOM所有交互靠表单提交和超链接。这样做的目的是强制你理解HTTP的无状态本质——每次请求都是全新的HttpServletRequest对象数据要靠request.setAttribute()传给JSP或者靠session跨请求保持。控制层Controller Layer标准HttpServlet子类。每个功能对应一个Servlet比如StudentAddServlet处理添加、StudentListServlet处理列表查询。这里的关键是web.xml中的映射配置它定义了URL路径到Servlet类的绑定关系。很多初学者以为注解WebServlet(/add)更方便但实际项目中web.xml的集中配置更利于运维人员快速定位路由规则也避免了IDE在热部署时因注解扫描失败导致的404。业务层Business LayerStudentService接口及其实现类。这里不做任何Spring的依赖注入而是用最原始的new StudentServiceImpl()方式获取实例。目的是让你看清所谓“服务层”本质就是一堆方法调用它的职责是协调DAO和处理业务规则而不是被框架管理的对象。数据访问层Data Access LayerStudentDAO接口 JdbcStudentDAO实现。用原生JDBC手动写PreparedStatement手动处理ResultSet手动关闭Connection、Statement、ResultSet。虽然繁琐但当你亲手写try...catch...finally释放资源时才会真正理解连接池的意义——为什么Druid要配置maxActive20因为你的JdbcStudentDAO里每执行一次查询就打开一个物理连接不回收就会耗尽数据库连接数。实体层Entity LayerStudentPOJO类只有字段、getter/setter、无参构造器。不加Lombok不加Jackson注解纯粹的Java Bean。这样设计是为了让JSP里的c:forEach items${studentList} varstu能直接通过反射调用getStuName()获取属性值——JSTL的EL表达式底层就是PropertyUtils.getProperty()它要求属性名必须严格匹配getter方法名。整个架构没有MVC框架的自动绑定、没有ORM的懒加载、没有AOP的事务代理。所有数据流转都靠你手动request.setAttribute(studentList, list)、手动session.setAttribute(currentUser, user)、手动response.sendRedirect(list.jsp)。这种“笨办法”恰恰是最高效的入门路径。我带过的学员里凡是能把这套流程完整跑通的后续学Spring MVC时对ModelAttribute、ModelAndView、RedirectAttributes的理解速度比别人快一倍不止——因为他们已经亲手做过这些事只是Spring把它自动化了而已。3. 核心细节解析从web.xml到JSP编译每一个环节都不能错3.1 web.xml那个被时代遗忘却至关重要的配置中心很多人以为web.xml是过时的古董其实它是整个Web应用的“宪法”。Tomcat启动时第一件事就是读取/WEB-INF/web.xml根据里面的配置初始化Servlet、Filter、Listener并建立URL映射关系。我们项目的web.xml核心配置如下?xml version1.0 encodingUTF-8? web-app xmlnshttp://xmlns.jcp.org/xml/ns/javaee xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd version4.0 !-- 应用名称 -- display-nameStudentManagementSystem/display-name !-- 全局上下文参数指定数据库驱动 -- context-param param-namedriverClassName/param-name param-valuecom.mysql.cj.jdbc.Driver/param-value /context-param !-- 全局初始化参数数据库连接URL -- context-param param-namejdbcUrl/param-name param-valuejdbc:mysql://localhost:3306/student_db?useSSLfalseamp;serverTimezoneAsia/Shanghaiamp;characterEncodingutf8/param-value /context-param !-- Servlet定义 -- servlet servlet-nameStudentListServlet/servlet-name servlet-classcom.example.servlet.StudentListServlet/servlet-class !-- 初始化参数指定每页显示条数 -- init-param param-namepageSize/param-name param-value10/param-value /init-param /servlet !-- Servlet映射 -- servlet-mapping servlet-nameStudentListServlet/servlet-name url-pattern/list/url-pattern /servlet-mapping !-- 默认欢迎文件 -- welcome-file-list welcome-fileindex.jsp/welcome-file /welcome-file-list !-- 错误页面配置 -- error-page error-code404/error-code location/error/404.jsp/location /error-page error-page error-code500/error-code location/error/500.jsp/location /error-page /web-app关键点解析context-param定义的是全局参数所有Servlet都能通过getServletContext().getInitParameter(driverClassName)获取适合配置数据库连接信息这类应用级常量。init-param定义的是Servlet级参数只能在对应Servlet内通过getInitParameter(pageSize)获取适合配置该Servlet特有的行为参数。url-pattern/list/url-pattern中的斜杠至关重要/list表示精确匹配/list/*表示路径匹配*.do表示扩展名匹配。如果写成list没斜杠Tomcat会认为这是相对于当前目录的相对路径导致404。welcome-file-list指定了根路径/访问时自动加载的页面但注意index.jsp必须放在Web应用根目录下不能放在/WEB-INF/里因为/WEB-INF/是受保护目录外部无法直接访问。提示IntelliJ IDEA创建Web项目时默认不生成web.xml需要手动在src/main/webapp/WEB-INF/下创建。而Eclipse的Dynamic Web Project向导会自动生成但版本可能为2.5需手动升级到4.0以支持jsp-config等新特性。3.2 JSP页面编码与EL表达式失效的真相JSP页面乱码、EL表达式不生效是新手最高频的两个问题。它们的根源都藏在JSP编译过程里。首先看编码问题。一个典型的JSP页面开头应该是% page languagejava contentTypetext/html; charsetUTF-8 pageEncodingUTF-8% !DOCTYPE html html head meta charsetUTF-8 title学生列表/title /head body h1学生信息/h1 c:forEach items${studentList} varstu p姓名${stu.stuName}学号${stu.stuId}/p /c:forEach /body /html这里三个编码声明缺一不可contentTypetext/html; charsetUTF-8告诉浏览器这个响应体是UTF-8编码的HTML。pageEncodingUTF-8告诉JSP引擎这个.jsp文件本身是UTF-8编码保存的用于正确读取文件内容。meta charsetUTF-8作为HTML文档的元信息是浏览器解析HTML时的后备编码声明。三者必须一致。如果.jsp文件用GBK保存但pageEncoding写UTF-8JSP引擎读取时就会乱码如果contentType写ISO-8859-1浏览器就会用Latin1解码中文全变成方块。再来看EL表达式失效。${studentList}不显示数据常见原因有三个JSP版本太低JSP 2.0以下默认禁用EL。解决方案是在page指令中显式开启% page isELIgnoredfalse %。但更根本的解决是确保web.xml声明的是Servlet 3.0规范即version3.0或更高因为JSP 2.1默认启用EL。作用域错误studentList是存在request作用域还是session作用域JSP里${studentList}默认从page→request→session→application顺序查找。如果Servlet里写的是session.setAttribute(studentList, list)那么JSP里必须写${sessionScope.studentList}。JSTL标签库未正确引入c:forEach需要JSTL支持。必须在web.xml中配置taglib或在JSP顶部添加% taglib prefixc urihttp://java.sun.com/jsp/jstl/core %并且/WEB-INF/lib/下必须有jstl.jar和standard.jarJSP 1.2或jakarta-taglibs-standard-1.1.2.jarJSP 2.0。IntelliJ IDEA中右键项目→Add Framework Support→选择Java EE Web Module会自动添加JSTL库。注意Eclipse中创建JSP文件时如果提示“JSP is not supported in this project”说明项目Facet没配置Web Module。右键项目→Properties→Project Facets→勾选Dynamic Web Module并设置版本推荐4.0。3.3 数据库连接与JDBC资源管理的生死线学生管理系统离不开数据库。我们用MySQL 8.0建表语句如下CREATE DATABASE student_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE student_db; CREATE TABLE student ( stu_id VARCHAR(12) PRIMARY KEY, stu_name VARCHAR(20) NOT NULL, stu_age INT, stu_gender ENUM(男,女), stu_class VARCHAR(20), stu_phone VARCHAR(15), create_time DATETIME DEFAULT CURRENT_TIMESTAMP ); INSERT INTO student VALUES (2021001, 张三, 20, 男, 计算机1班, 13800138000, NOW()), (2021002, 李四, 19, 女, 软件工程2班, 13900139000, NOW());关键点在于JDBC连接管理。JdbcStudentDAO的getConnection()方法必须这样写private Connection getConnection() throws SQLException { String driver getServletContext().getInitParameter(driverClassName); String url getServletContext().getInitParameter(jdbcUrl); String username root; String password 123456; try { Class.forName(driver); // 加载驱动MySQL 8.0可省略但保留更兼容 return DriverManager.getConnection(url, username, password); } catch (ClassNotFoundException e) { throw new RuntimeException(JDBC Driver not found, e); } }而查询方法必须严格遵循资源释放规范public ListStudent findAll() { ListStudent list new ArrayList(); String sql SELECT * FROM student ORDER BY create_time DESC; Connection conn null; PreparedStatement ps null; ResultSet rs null; try { conn getConnection(); ps conn.prepareStatement(sql); rs ps.executeQuery(); while (rs.next()) { Student stu new Student(); stu.setStuId(rs.getString(stu_id)); stu.setStuName(rs.getString(stu_name)); stu.setStuAge(rs.getInt(stu_age)); stu.setStuGender(rs.getString(stu_gender)); stu.setStuClass(rs.getString(stu_class)); stu.setStuPhone(rs.getString(stu_phone)); list.add(stu); } } catch (SQLException e) { e.printStackTrace(); // 实际项目应记录日志 } finally { // 必须按rs→ps→conn顺序关闭 if (rs ! null) try { rs.close(); } catch (SQLException e) {} if (ps ! null) try { ps.close(); } catch (SQLException e) {} if (conn ! null) try { conn.close(); } catch (SQLException e) {} } return list; }为什么关闭顺序必须是rs→ps→conn因为ResultSet依赖StatementStatement依赖Connection。如果先关connrs就变成无效游标调用rs.next()会抛SQLException。而try-with-resources语法Java 7可以自动处理但为了教学清晰我们坚持手动关闭。实操心得本地测试时建议在MySQL配置文件my.cnf中添加wait_timeout288008小时避免连接空闲超时断开。生产环境必须用连接池如Druid但学习阶段亲手写conn.close()比配置Druid的maxWait参数更能理解连接复用的价值。4. 完整实操流程从Eclipse创建项目到Tomcat部署上线4.1 Eclipse创建基于Maven的Servlet项目最稳妥的起点虽然标题说“附完整源码”但源码的价值在于可复现。下面是从零开始的详细步骤确保你在任何一台装了JDK 8和Eclipse的电脑上都能10分钟内跑起来。第一步创建Maven Web项目Eclipse菜单栏File → New → Other → Maven → Maven Project勾选“Create a simple projectskip archetype selection”NextGroup Id填com.exampleArtifact Id填student-management-systemVersion用默认0.0.1-SNAPSHOTFinish此时项目结构是标准Maven布局但缺少Web目录。右键项目→Properties→Project Facets→勾选“Dynamic Web Module”Version选“4.0”同时勾选“Java”和“JavaScript”。点击“Further configuration available...”在“Content directory”中填src/main/webapp点击OK。Eclipse会自动创建src/main/webapp/WEB-INF/web.xml。第二步配置Maven依赖pom.xml在pom.xml的dependencies中添加!-- Servlet API -- dependency groupIdjavax.servlet/groupId artifactIdjavax.servlet-api/artifactId version4.0.1/version scopeprovided/scope /dependency !-- JSP API -- dependency groupIdjavax.servlet.jsp/groupId artifactIdjavax.servlet.jsp-api/artifactId version2.3.3/version scopeprovided/scope /dependency !-- JSTL -- dependency groupIdjavax.servlet/groupId artifactIdjstl/artifactId version1.2/version /dependency !-- MySQL JDBC Driver -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.33/version /dependency注意scopeprovided/scope表示这些jar由Tomcat提供打包时不包含避免冲突。第三步创建目录结构与核心文件按以下路径创建文件src/main/java/com/example/servlet/StudentListServlet.javasrc/main/java/com/example/dao/StudentDAO.javasrc/main/java/com/example/dao/JdbcStudentDAO.javasrc/main/java/com/example/entity/Student.javasrc/main/webapp/index.jspsrc/main/webapp/list.jspsrc/main/webapp/add.jspsrc/main/webapp/WEB-INF/web.xml第四步编写StudentListServlet核心控制器package com.example.servlet; import com.example.dao.StudentDAO; import com.example.dao.JdbcStudentDAO; import com.example.entity.Student; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; WebServlet(/list) public class StudentListServlet extends HttpServlet { private StudentDAO studentDAO; Override public void init() throws ServletException { // 初始化DAO实例 this.studentDAO new JdbcStudentDAO(); } Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 查询所有学生 ListStudent studentList studentDAO.findAll(); // 将数据存入request作用域 request.setAttribute(studentList, studentList); // 转发到list.jsp request.getRequestDispatcher(/list.jsp).forward(request, response); } }第五步配置Tomcat服务器Eclipse菜单栏Window → Show View → Servers点击“No servers are available. Click this link to create a new server.”选择Apache → Tomcat v9.0 ServerNextBrowse选择Tomcat安装目录如D:\apache-tomcat-9.0.83Finish右键Servers视图中的Tomcat → Add Deployment → 选择你的项目Finish右键Tomcat → Start控制台输出INFO: Server startup in [xxx] milliseconds即启动成功。第六步访问测试浏览器打开http://localhost:8080/student-management-system/list如果看到学生列表说明Servlet、DAO、JSP全部打通。此时你可以用Chrome开发者工具的Network标签查看HTTP请求的Status Code、Response Headers确认Content-Type: text/html;charsetUTF-8、Response Body确认HTML结构正确。实操心得如果访问/list报404先检查Eclipse控制台是否有SEVERE: Error starting static Resources错误这通常意味着web.xml路径不对或Tomcat没识别到Web应用如果报500看控制台堆栈90%是ClassNotFoundException缺jar包或SQLException数据库连不上。我的经验是遇到500先看最后一行Caused by:那里才是真正的错误源头。4.2 IntelliJ IDEA中创建JSP项目避坑指南IntelliJ IDEA对JSP的支持不如Eclipse成熟新手容易掉坑。以下是关键配置步骤第一步创建Web Application项目File → New → Project → Java Enterprise → Web Application不要选Maven先保证基础功能勾选“Create web.xml”和“Add sample code”Next项目名填student-management-ideaFinish第二步解决JSP语法高亮和Color Scheme问题问题IDEA中JSP文件没有语法高亮编辑器主题里找不到JSP相关设置。解决File → Settings → Editor → Color Scheme → General → Syntax → JSP勾选“Enable highlighting for JSP files”。如果列表里没有JSP说明插件未启用Settings → Plugins → 搜索“JSP Support”确保已启用。第三步手动添加JSTL库IDEA不会自动添加JSTL。下载jstl-1.2.jar和standard-1.1.2.jar放到/WEB-INF/lib/下。右键lib文件夹 → Add as Library确保在Project Structure → Libraries中能看到这两个jar。第四步配置Tomcat并部署Run → Edit Configurations → → Tomcat Server → Local在Deployment标签页点击 → Artifact → 选择你的项目名称:war explodedApplication context填/student-idea避免根路径冲突启动后访问http://localhost:8080/student-idea/list注意IDEA中JSP编译后的Java类默认在out/artifacts/xxx_war_exploded/下的org/apache/jsp/目录。如果你想查看list_jsp.java源码就在该路径下找。这比Eclipse的work/Catalina/localhost/xxx/org/apache/jsp/更直观也印证了JSP本质就是Servlet。5. 常见问题与排查技巧实录那些让我熬夜到凌晨三点的Bug5.1 “HTTP Status 404 – The requested resource [ /xxx ] is not available” —— URL映射之谜这是最让人抓狂的错误。表面看是路径不对但背后有五种完全不同的原因现象可能原因排查命令/方法解决方案访问/list报404但/index.jsp正常web.xml中servlet-mapping的url-pattern写错查看Tomcat启动日志搜索Mapping servlet确保url-pattern/list/url-pattern不是list或/list/访问/list报404且Tomcat日志无任何映射信息web.xml未被Tomcat加载检查/WEB-INF/web.xml文件是否存在XML格式是否正确用在线XML校验工具重新创建web.xml确保根元素是web-appnamespace正确访问/list报404日志显示Mapping servlet StudentListServlet to [/list]Servlet类路径错误在web.xml中检查servlet-class是否为完整包名如com.example.servlet.StudentListServlet确认.class文件在WEB-INF/classes/com/example/servlet/下访问/list报404但/servlet/StudentListServlet能访问使用了WebServlet注解但web.xml中web-app版本低于3.0查看web.xml的version属性升级web.xml到version3.0或更高访问/list报404且项目在Servers视图中显示为“[Stopped]”Tomcat未成功部署该项目右键Servers中的Tomcat → Clean…然后重启清理Tomcat工作目录work/Catalina/localhost/独家技巧在StudentListServlet的doGet()方法第一行加System.out.println(StudentListServlet executed!);如果控制台没输出说明请求根本没到达Servlet问题一定在映射层如果输出了但页面还是404说明是转发或重定向的问题。5.2 “HTTP Status 500 – java.lang.NullPointerException” —— 空指针的七种死法NPE是Java Web开发的“家常便饭”但在ServletJSP场景下它往往指向特定的资源管理漏洞DAO未初始化studentDAO.findAll()前没调用init()方法studentDAO为null。解决在Servlet的init()方法中初始化DAO或在doGet()中判断if (studentDAO null) studentDAO new JdbcStudentDAO();数据库连接失败DriverManager.getConnection()返回null但代码没判空。解决JDBC规范规定连接失败时抛SQLException不是返回null。所以NPE通常是因为conn对象在try块外声明catch中没赋值导致finally里conn.close()时为null。JSP中EL表达式取值为空${stu.stuName}中stu为null调用getStuName()时NPE。解决用EL的空安全操作符${stu.stuName ! null ? stu.stuName : 未知}或在JSTL中用c:if test${not empty stu}request.getAttribute()返回nullServlet里没setAttribute()JSP里直接${studentList}。解决在JSP顶部加c:if test${empty studentList}暂无数据/c:if避免遍历null集合。web.xml参数读取失败getServletContext().getInitParameter(jdbcUrl)返回null后续拼接字符串时报NPE。解决在getConnection()方法开头加if (url null) throw new RuntimeException(jdbcUrl not configured in web.xml);ResultSet未判空rs.getString(stu_name)返回null但代码直接赋值给非null字段。解决数据库字段设为NOT NULL或Java代码中用StringUtils.defaultString(rs.getString(stu_name))IDE缓存导致class文件未更新修改了Servlet代码但Tomcat运行的还是旧class。解决Eclipse中Project → CleanIDEA中Build → Clean and rebuildTomcat中右键→Clean…实操心得我有个铁律——只要出现NPE第一反应不是看堆栈而是打开Tomcat的logs/catalina.out搜索Caused by:。90%的NPE前面都有更早的SQLException或ClassNotFoundException那是真正的病因。比如Caused by: java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver说明MySQL驱动jar没放对位置这时候修NPE代码毫无意义。5.3 JSP页面中文乱码终极解决方案乱码问题本质是字符集在传输链路上的不一致。我们梳理完整链条浏览器输入URL → HTTP请求GET/POST→ Tomcat接收 → Servlet处理 → JSP渲染 → HTTP响应 → 浏览器显示每个环节都可能出错GET请求中文乱码浏览器将中文参数用UTF-8编码Tomcat默认用ISO-8859-1解码结果乱码。解决在web.xml中配置filter或在Servlet中手动转码new String(request.getParameter(name).getBytes(ISO-8859-1), UTF-8)POST请求中文乱码必须在request.getParameter()之前调用request.setCharacterEncoding(UTF-8)。解决写一个CharacterEncodingFilter在doFilter()中执行request.setCharacterEncoding(UTF-8)并配置到web.xml。JSP页面乱码如前所述pageEncoding、contentType、meta三者不一致。解决统一设为UTF-8并确保.jsp文件本身用UTF-8保存Eclipse中右键文件→Properties→Resource→Text file encoding。数据库存储乱码MySQL连接URL没加characterEncodingutf8或数据库、表、字段的collation不是utf8mb4_unicode_ci。解决执行SHOW VARIABLES LIKE character_set_%;确认character_set_client、character_set_connection、character_set_results均为utf8mb4。Tomcat控制台乱码Windows CMD默认GBKTomcat日志输出中文变乱码。解决修改bin/catalina.bat在set JAVA_OPTS行后添加-Dfile.encodingUTF-8。终极验证法在Servlet中写System.out.println(中文测试 request.getParameter(name)); // 控制台输出 request.setAttribute(testStr, 中文测试); request.getRequestDispatcher(/test.jsp).forward(request, response);如果控制台显示正常但JSP页面乱码问题一定在JSP编码如果控制台就乱码问题在请求编码。5.4 “The requested resource is not available” 与 “HTTP Status 404” 的本质区别很多人混淆这两个错误其实它们代表完全不同的故障层级“The requested resource is not available”这是Tomcat的默认错误页面文字当发生404时Tomcat会返回这个HTML页面。它本身不是错误码而是404的友好提示。“HTTP Status 404”这是HTTP协议规定的状态码表示服务器找不到请求的资源。它是一个数字不是文字。真正要关注的是HTTP状态码。用Chrome开发者工具的Network标签点击请求看Headers → Response Headers → Status如果是404 Not Found说明资源确实不存在如果是500 Internal Server Error说明服务器内部出错。最后分享一个小技巧在web.xml中配置自定义错误页面后Tomcat就不会显示“The requested resource is not available”了而是显示你写的404.jsp。这不仅是美化更是调试利器——你可以在404.jsp里打印request.getRequestURL()和request.getQueryString()实时看到用户到底访问了什么URL比翻日志快十倍。
网站建设高端定制企业官网