I have the following web.xml file:
<?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>
which works fine and if I go to localhost:8080/myproject/api/ping I have expected response.
But if I change "url-pattern" to "/api/*" a request to the same URL returns 404.
Do you have any idea why this can happen?
Here is the rest of my configuration.
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 {
...
}
My code:
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!";
}
}
I run the application with the following command:
./gradlew clean jettyRunWar
The url-pattern is the prefix or base of the servlet, in this case the Jersey servlet. It's how the servlet container knows which servlet to send the request to.
So with /api/*
You are telling the servlet container that the base of the Jersey app is /api
. This base really only matters to the servlet container. Jersey handles/maps everything after it.
So a request to /api/ping
first gets the /api
cut off, since it is just the app base. Then Jersey tries to locate /ping
as a root resource class, meaning it should be a class annotation with @Path("ping")
. Since it can't find it, you get a 404.
So if you add the /api/*
, with your current code, the request should be to /api/api/ping
Generally you would not want to have the app base name on the resource class though. You should just have @Path("ping")
on the resource class, and keep /api/*
in the mapping. Just take out the @Path
annotation from the ping()