Tomcat 8是否读取Java REST API的web.xml和context.xml?排查HTTPS 404
你遇到的这个问题很典型——HTTP下正常的REST接口,切到HTTPS就报404,日志还误报“文件不存在”,大概率是Tomcat对HTTPS请求的路由逻辑出了问题,或者配置文件没被正确加载。先给你说几个实锤的方法,确认Tomcat到底有没有读你的web.xml和context.xml,再结合你的配置给几个额外排查点:
一、确认Tomcat是否读取了你的web.xml
方法1:加个监听日志,直观验证
写一个简单的Servlet上下文监听器,Tomcat加载web.xml时会触发它的初始化方法,直接打日志就能确认:
import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class AppLoadListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { // 直接打印到Tomcat控制台或日志文件 System.out.println("[MyProject] 应用web.xml已被Tomcat加载!上下文初始化完成"); } @Override public void contextDestroyed(ServletContextEvent sce) { // 可选:销毁时的日志 System.out.println("[MyProject] 应用上下文已销毁"); } }
把这个类放到你的项目源码里(比如com.yourpackage.listener包下),然后在web.xml里注册这个监听器:
<listener> <listener-class>com.yourpackage.listener.AppLoadListener</listener-class> </listener>
重启Tomcat,去catalina.out或者localhost.log里找这个打印的日志,能找到就说明web.xml被正常读取了。
方法2:检查Tomcat启动日志的部署痕迹
Tomcat启动时会输出部署应用的详细日志,找这两类内容:
- 部署WAR包的日志:
INFO: Deploying web application archive [/path/to/tomcat/webapps/MyJavaProject.war] - Jersey Servlet初始化日志:因为你配置了
<load-on-startup>1</load-on-startup>,Tomcat启动时会提前加载ServletAdaptor,日志里会出现com.sun.jersey.server.impl.container.servlet.ServletAdaptor相关的初始化信息,比如INFO: Initiating Jersey application, version 'Jersey x.x.x'
如果能找到这些日志,说明web.xml里的Servlet配置已经被识别了。
方法3:故意搞坏web.xml语法,看报错
把web.xml里的某个标签写错,比如把<servlet>改成<servlet-typo>,然后重启Tomcat。如果Tomcat启动时抛出SAXParseException这类XML解析错误,就说明它确实在解析你的web.xml——要是没报错,那大概率Tomcat根本没读到这个文件。
二、确认Tomcat是否读取了应用内的context.xml
注意:你说的应用内的context.xml应该是放在META-INF/context.xml(不是Tomcat conf目录下的全局context.xml),确认方法如下:
方法1:加个测试Resource,代码验证
在你的context.xml里加一个测试用的资源配置:
<?xml version="1.0" encoding="UTF-8"?> <Context reloadable="true"> <!-- 加个测试用的字符串资源 --> <Resource name="test/MyCheckValue" auth="Container" type="java.lang.String" value="TomcatReadMyContextXML"/> </Context>
然后写一个简单的REST接口来读取这个资源:
import javax.naming.Context; import javax.naming.InitialContext; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path("/check-context") public class ContextCheckResource { @GET @Produces(MediaType.TEXT_PLAIN) public String checkContextLoad() { try { Context initCtx = new InitialContext(); Context envCtx = (Context) initCtx.lookup("java:comp/env"); String testValue = (String) envCtx.lookup("test/MyCheckValue"); return "✅ 应用context.xml已被读取!测试值:" + testValue; } catch (Exception e) { return "❌ 读取context.xml配置失败:" + e.getMessage(); } } }
部署后用HTTPS调用https://www.mydomain.co.uk:8443/MyJavaProject/check-context(注意端口!),如果返回成功信息,说明context.xml被Tomcat读取了。
方法2:查Tomcat部署日志
Tomcat部署带有META-INF/context.xml的应用时,会输出类似这样的日志:
INFO: Context initialization from ServletContext resource [/META-INF/context.xml]
去catalina.out里搜这句话,找到就说明应用的context.xml被加载了。
方法3:故意搞坏context.xml语法
和web.xml的方法一样,把<Context>改成<Context-typo>,重启Tomcat,如果部署时报XML解析错误,就说明Tomcat在读取这个文件。
结合你的配置的额外排查点
看了你提供的配置文件,还有几个容易踩坑的地方:
HTTPS端口是否正确:Tomcat默认HTTPS端口是8443,你之前HTTP用的是8080,启用SSL后,直接用
https://www.mydomain.co.uk/MyJavaProject/...是不对的(除非你配置了反向代理把443转成8443,或者修改了Tomcat的HTTPS端口为443)。先确认你的HTTPS请求端口是否正确,应该是https://www.mydomain.co.uk:8443/MyJavaProject/context_string/path_params。web.xml里的security-constraint是否冲突:你配置了
<transport-guarantee>CONFIDENTIAL</transport-guarantee>,这个会强制把/context_string/*路径的HTTP请求重定向到HTTPS,但如果Tomcat的SSL配置有问题,可能导致重定向后的路径异常。可以先临时注释掉这个security-constraint,测试HTTPS请求是否正常,排除这个因素。context.xml的空配置可能多余:你的context.xml里写了
<Context docBase="" path="" reloadable="true">,空的path和docBase其实没必要——Tomcat部署WAR时,默认会把WAR文件名作为context path,docBase自动指向WAR包路径。改成<Context reloadable="true"></Context>反而更稳妥,避免可能的路径冲突。WAR包解压是否完整:虽然你说权限是777,但还是要检查
webapps/MyJavaProject目录下的文件是否完整,比如WEB-INF/lib下的Jersey、Javax库是否都存在,WEB-INF/classes下的class文件是否和你的项目一致。Tomcat的SSL Connector配置是否正确:去Tomcat的
conf/server.xml里检查SSL Connector的配置,确保证书路径、密码都正确,没有启动错误。比如:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true"> <SSLHostConfig> <Certificate certificateKeystoreFile="conf/your-valid-cert.jks" certificateKeystorePassword="your-keystore-password" type="RSA" /> </SSLHostConfig> </Connector>
先按上面的方法确认配置文件是否被加载,再排查这些额外点,应该能快速定位到404的原因。
内容的提问来源于stack exchange,提问作者Think.Smart

