为何Servlet在Wildfly中返回403,在Tomcat中返回200?
问题:Wildfly 32部署注解式Servlet返回403 Forbidden,Tomcat运行正常
背景
我开发了一个极简WAR包,部署到Tomcat 9.0.43可正常响应请求,但部署到Wildfly 32.0.0.1 beta时,访问返回403 Forbidden。WAR包采用注解式Servlet实现,相关代码及配置如下:
Servlet源码
package infoservlet; import java.io.IOException; import java.io.PrintWriter; import java.time.LocalDateTime; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/") public class InfoServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer = resp.getWriter(); writer.append(LocalDateTime.now() + "\n"); writer.flush(); } }
Maven POM配置
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>markscottwright</groupId> <artifactId>infoservlet</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <properties> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> <failOnMissingWebXml>false</failOnMissingWebXml> </properties> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>${project.artifactId}</finalName> </build> </project>
部署与访问细节
- Wildfly部署:将WAR包复制到
standalone/deployments目录,已生成infoservlet.war.deployed文件,确认部署成功 - Wildfly启动命令:
standalone.sh -b 127.0.0.1 -Djboss.server.base.dir=/tmp/wildfly3/standalone -Djboss.socket.binding.port-offset=300 - Wildfly访问结果:执行
curl localhost:8380/infoservlet/ -I返回403HTTP/1.1 403 Forbidden Connection: keep-alive Content-Type: text/html;charset=UTF-8 Content-Length: 68 Date: Tue, 09 Apr 2024 20:40:02 GMT - Tomcat访问结果:执行
curl localhost:8080/infoservlet/ -I返回200正常HTTP/1.1 200 Content-Length: 27 Date: Tue, 09 Apr 2024 20:40:31 GMT
推测是Wildfly安全设置导致,请问哪里操作有误?
解答
核心原因
- Wildfly默认安全约束拦截根路径:Wildfly内置的默认安全规则会对
/*路径进行拦截,要求请求必须经过授权。你的Servlet映射路径为/,正好命中这个规则,导致未授权请求返回403。 - API版本兼容性差异:Wildfly 32默认基于Jakarta EE 10,而你的项目使用的是Java EE 8的
javax.servlet-api4.0.1,虽然Wildfly做了兼容处理,但注解路径的解析逻辑和Tomcat存在差异,进一步放大了冲突。
解决方法
方法1:修改Servlet映射路径(快速解决)
将@WebServlet("/")修改为具体的子路径,比如@WebServlet("/info"),之后访问localhost:8380/infoservlet/info即可正常获取响应。
方法2:添加web.xml覆盖默认安全约束
在src/main/webapp/WEB-INF下创建web.xml文件,添加以下内容取消对所有路径的安全拦截:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <security-constraint> <web-resource-collection> <web-resource-name>Unsecured Resources</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <user-data-constraint> <transport-guarantee>NONE</transport-guarantee> </user-data-constraint> </security-constraint> </web-app>
方法3:升级为Jakarta EE依赖(长期推荐)
Wildfly 32原生支持Jakarta EE 10,建议将项目依赖升级为Jakarta版本以减少兼容性问题:
- 修改POM中的Servlet依赖:
<dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>6.0.0</version> <scope>provided</scope> </dependency> - 修改Servlet源码中的包导入:
将所有javax.servlet.*和javax.servlet.http.*替换为jakarta.servlet.*和jakarta.servlet.http.*
内容的提问来源于stack exchange,提问作者Mark Wright
相关产品推荐
相关产品推荐

