Tomcat访问WEB-INF下index.html出现404错误求助
咱们一步步拆解你的问题——这是典型的Servlet规范+Jersey路由配置踩坑场景:
1. 先搞懂WEB-INF的核心规则(为什么放这里肯定不行)
根据Servlet官方规范,WEB-INF是服务器端的受保护目录,外部HTTP请求(比如浏览器直接访问)完全无法直接读取这个目录下的任何资源。不管你把index.html放到WEB-INF根下,还是错误地塞进WEB-INF/lib(这个目录是专门放Java依赖jar包的,绝对不能放静态HTML/CSS/JS),都不可能通过浏览器URL直接访问到。只有服务器端的代码(比如Servlet、JSP)通过RequestDispatcher转发,才能读取WEB-INF内的资源。
2. 你的web.xml配置放大了问题
看你web.xml里的Servlet映射:
<servlet-mapping> <servlet-name>OpenAPI</servlet-name> <url-pattern>/api/*</url-pattern> <url-pattern>*.html</url-pattern> </servlet-mapping>
你把所有*.html请求都交给了Jersey的ServletContainer处理,但Jersey是REST框架,它不会默认处理静态HTML文件。哪怕你把index.html放到WEB应用的根目录(和WEB-INF同级),这个映射也会把请求拦截,导致Tomcat自带的静态资源处理器(DefaultServlet)根本没机会处理这个请求。
另外,你的Conductor类用了@ApplicationPath("/"),这会让Jersey接管所有根路径的请求,进一步覆盖了Tomcat处理静态资源的逻辑。
3. 正确的解决步骤
步骤1:把index.html放到正确位置
将index.html移动到WEB应用的根目录(也就是和WEB-INF文件夹同级的位置,比如你的项目结构里是webapp/index.html)。
步骤2:调整web.xml的Servlet映射
去掉*.html的URL模式,让Jersey只处理API请求:
<servlet-mapping> <servlet-name>OpenAPI</servlet-name> <url-pattern>/api/*</url-pattern> </servlet-mapping>
这样Tomcat的DefaultServlet会自动处理所有静态资源请求(包括index.html),同时你的welcome-file-list配置也会生效——访问http://localhost:9999/时会自动加载根目录的index.html。
步骤3:(可选)如果必须保留Jersey的根路径映射
如果你因为业务原因不能修改@ApplicationPath("/"),那需要在Jersey中配置允许访问静态资源。可以在Conductor的getClasses()方法中添加Jersey的静态资源处理特性,或者添加属性配置:
// 在Conductor类中重写getProperties方法 @Override public Map<String, Object> getProperties() { Map<String, Object> props = new HashMap<>(); // 配置允许访问指定静态资源 props.put("jersey.config.servlet.filter.staticContentRegex", "/(index.html|css|js)/.*"); return props; }
不过这种方式比较复杂,优先推荐步骤2的方案,更符合Servlet规范的最佳实践。
验证
做完以上修改后重启Tomcat:
- 访问
http://localhost:9999/index.html应该能正常加载页面 - 访问
http://localhost:9999/会自动跳转到index.html(因为welcome-file-list的配置) - 你的API接口
http://localhost:9999/api/xxx依然能正常工作
内容的提问来源于stack exchange,提问作者Tasos

