You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jersey 3与Tomcat 10集成返回404错误求助

问题:Tomcat 10 + Jersey 3 集成后接口返回404

基于Tomcat 10、Java 17、Gradle构建的应用,集成Jersey 3 Servlet后访问接口始终返回404。WAR包已正常部署到webapps目录(同目录其他WAR可正常运行),以下是相关配置与修复方案:


原配置代码

web.xml 配置

<servlet>
    <servlet-name>jersey-servlet</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
         <param-name>jakarta.jws.rs.application</param-name>
         <param-value>base.tests.war.logging</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>jersey-servlet</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

测试资源类

package base.tests.war.logging;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;

@Path("/rest")
public class MainResource {
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String getMain() {
        return "Main";
    }
    
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    @Path("/commons")
    public Response getCommonsLogging() {
        org.apache.commons.logging.LogFactory.getLog(MainResource.class).info("Commons logging logger.");
        return Response.ok().entity("Commons logging!!!").build();
    }
}

Gradle Jersey 相关依赖

providedCompile (
            // jersey dependencies
            [group: 'jakarta.ws.rs', name: 'rs-api', version: 3.1.0],

            [group: 'org.glassfish.jersey.core', name: 'jersey-server', version:3.1.1 ],
            [group: 'org.glassfish.jersey.core', name: 'jersey-common', version:3.1.1 ],
            [group: 'org.glassfish.jersey.core', name: 'jersey-client', version:3.1.1 ],
            [group: 'org.glassfish.jersey.containers', name: 'jersey-container-servlet', version:3.1.1 ],
            [group: 'org.glassfish.jersey.inject', name: 'jersey-hk2', version: 3.1.1],
            [group: 'org.glassfish.jakarta.servlet', name: 'servlet-api', version: 6.0.0],
            [group: 'org.objectweb.asm', name: 'asm', version: '3.1.0'],
)

修复方案

1. 修正 web.xml 初始化参数

原配置存在两个问题:参数名称错误,且参数值应为资源扫描包或自定义Application类,而非包名。

修改后的 web.xml(采用自动扫描包方式,无需自定义Application类):

<servlet>
    <servlet-name>jersey-servlet</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
         <param-name>jersey.config.server.provider.packages</param-name>
         <param-value>base.tests.war.logging</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>jersey-servlet</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

2. 调整资源类路径映射

Servlet已映射到/rest/*,资源类的@Path无需重复添加/rest,否则会导致路径叠加。修改后的资源类:

package base.tests.war.logging;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;

@Path("/") // 对应Servlet的/rest/*根路径
public class MainResource {
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String getMain() {
        return "Main";
    }
    
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    @Path("/commons")
    public Response getCommonsLogging() {
        org.apache.commons.logging.LogFactory.getLog(MainResource.class).info("Commons logging logger.");
        return Response.ok().entity("Commons logging!!!").build();
    }
}

此时正确访问路径:

  • 主接口:http://localhost:8080/你的应用上下文/rest
  • Commons接口:http://localhost:8080/你的应用上下文/rest/commons

3. 修正 Gradle 依赖配置

原配置用providedCompile包含Jersey核心依赖,会导致WAR包缺失必要类。需将Jersey核心依赖改为implementation,仅保留Servlet API为providedCompile,同时升级ASM版本适配Java 17:

dependencies {
    // Jersey核心依赖,需要打包到WAR中
    implementation (
        [group: 'jakarta.ws.rs', name: 'jakarta.ws.rs-api', version: '3.1.0'],
        [group: 'org.glassfish.jersey.core', name: 'jersey-server', version:'3.1.1'],
        [group: 'org.glassfish.jersey.core', name: 'jersey-common', version:'3.1.1'],
        [group: 'org.glassfish.jersey.core', name: 'jersey-client', version:'3.1.1'],
        [group: 'org.glassfish.jersey.containers', name: 'jersey-container-servlet', version:'3.1.1'],
        [group: 'org.glassfish.jersey.inject', name: 'jersey-hk2', version: '3.1.1'],
        [group: 'org.objectweb.asm', name: 'asm', version: '9.5'] // 升级到支持Java17的版本
    )
    // Servlet API由Tomcat提供,无需打包
    providedCompile 'org.glassfish.jakarta.servlet:jakarta.servlet-api:6.0.0'
}

4. 验证部署

  1. 重新构建WAR包:./gradlew war
  2. 将WAR包放入Tomcat webapps目录,启动Tomcat
  3. 检查logs/catalina.out日志,确认存在Jersey初始化日志(如Initializing Jersey application, version Jersey: 3.1.1)
  4. 访问接口验证响应正常

内容的提问来源于stack exchange,提问作者AswAce

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 19:40:56