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

如何在web.xml中处理多个精确匹配的REST服务映射?

如何在Jersey 2.42中实现多个精确URL匹配的REST服务

需要创建包含多个精确匹配的REST服务,使用Jersey 2.42,且不能使用/*模式(因为有其他过滤器需要处理对应请求)。当前配置下请求无法正常工作:web.xml中给Jersey Servlet映射了/foo和/bar两个精确路径,但对应的资源类使用@Path("/foo")和@Path("/bar")时,请求会返回404。

问题原因

当Servlet的url-pattern是精确匹配(比如/foo)时,Jersey会将请求的路径去掉Servlet映射的前缀部分,用剩余的路径去匹配资源类的@Path注解。比如请求/foo时,Jersey内部处理的路径是空字符串,而资源类的@Path("/foo")无法匹配空路径,导致404。


解决方案一:调整资源类的@Path为根路径

保持web.xml的Servlet映射不变,将每个资源类的@Path改为"/",因为Jersey处理的是去掉Servlet前缀后的路径:

原web.xml(无需修改)

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet>
        <servlet-name>main-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>com.test</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>main-servlet</servlet-name>
        <url-pattern>/foo</url-pattern>
        <url-pattern>/bar</url-pattern>
    </servlet-mapping>
</web-app>

修改后的FooResource

@Path("/")
public class FooResource {
    @GET
    public String foo() {
        return "Foo";
    }
}

修改后的BarResource

@Path("/")
public class BarResource {
    @GET
    public String bar() {
        return "Bar";
    }
}

此时请求/foo时,Jersey用空路径匹配FooResource的@Path("/");请求/bar时匹配BarResource的@Path("/"),Servlet映射已完成请求分流,两者互不干扰。


解决方案二:为每个精确匹配创建独立Servlet

如果希望资源类保留原有的@Path,可以为每个精确路径创建单独的Jersey Servlet,每个Servlet只映射一个精确路径:

修改后的web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <!-- 处理/foo的Servlet -->
    <servlet>
        <servlet-name>foo-servlet</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.classnames</param-name>
            <param-value>com.test.FooResource</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>foo-servlet</servlet-name>
        <url-pattern>/foo</url-pattern>
    </servlet-mapping>

    <!-- 处理/bar的Servlet -->
    <servlet>
        <servlet-name>bar-servlet</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.classnames</param-name>
            <param-value>com.test.BarResource</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>bar-servlet</servlet-name>
        <url-pattern>/bar</url-pattern>
    </servlet-mapping>
</web-app>

资源类保持不变

@Path("/foo")
public class FooResource {
    @GET
    public String foo() {
        return "Foo";
    }
}
@Path("/bar")
public class BarResource {
    @GET
    public String bar() {
        return "Bar";
    }
}

这种方式每个Servlet独立负责一个路径,避免匹配冲突,但会增加Servlet数量,适合路径数量较少的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 16:54:53