为什么这个<servlet-mapping>在Jersey中破坏了我的REST API?

时间:2015-08-29 23:10:56

标签: java gradle jersey jetty web.xml

我有以下web.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
    <display-name>jersey sample</display-name>
    <servlet>
        <servlet-name>Jersey</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>org.myproject</param-value>
        </init-param>

        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Jersey</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

哪个工作正常,如果我去localhost:8080 / myproject / api / ping我预计会有回复。

但如果我改变&#34; url-pattern&#34;到&#34; / api / *&#34;对同一URL的请求将返回404。

你知道为什么会这样吗?

以下是我配置的其余部分。

的build.gradle:

group 'myproject'
version '0.0'

apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'jetty'


sourceCompatibility = 1.8


repositories {
    mavenCentral()
}


dependencies {
    compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.14'
    testCompile 'org.testng:testng:5.14.2'
}

test {
    ...
}

我的代码:

package org.myproject;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/api")
public class Api {
    @GET
    @Path("/ping")
    @Produces(MediaType.TEXT_PLAIN)
    public String ping() {
        return "Pong!";
    }

}

我使用以下命令运行应用程序:

./gradlew clean jettyRunWar 

1 个答案:

答案 0 :(得分:3)

url-pattern是前缀或servlet的基础,在本例中是Jersey servlet。它是servlet容器如何知道将请求发送到哪个servlet的。

所以使用/api/*您告诉servlet容器Jersey应用程序的基础是/api。这个基础真的只对servlet容器有用。泽西岛处理/映射后的所有内容。

因此,/api/ping的请求首先会被/api切断,因为它只是应用程序库。然后Jersey尝试将/ping定位为 root 资源类,这意味着它应该是带有@Path("ping")注释。由于它无法找到它,因此您获得了404。

因此,如果您使用当前代码添加/api/*,请求应为/api/api/ping

通常,您不希望在资源类上拥有应用程序基本名称。您应该在资源类上有@Path("ping"),并在映射中保留/api/*。只需从@Path

中取出ping()注释即可
相关问题