Java 泽西岛在调用正确的@Path 后返回 404
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19904538/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Jersey returning 404, after invoking the correct @Path
提问by user2978801
This thing is puzzling me already for quite some time.. I am trying to embed a Jersey container within Jetty. Following the examples I am able to embed Jersey, and I see my exposed REST method is being exposed. however, for some weird reason my Jersey does return a 404. It looks like Jersey is not capable to resolve the correct endpoint. Unfortunately it doesn't tell me why, but just throws a NotFoundException :-(.
这件事已经让我困惑了很长一段时间..我正在尝试在 Jetty 中嵌入一个 Jersey 容器。按照示例,我能够嵌入 Jersey,并且我看到我公开的 REST 方法正在公开。但是,出于某种奇怪的原因,我的 Jersey 确实返回了 404。看起来 Jersey 无法解析正确的端点。不幸的是,它没有告诉我原因,只是抛出了一个 NotFoundException :-(。
I am 100% certain my method is invoked. The System.out.println within that method is shown in the console, and my Eclipse debugger clearly passes the set breakpoint. It doesn't matter whether I use Jersey 2.0, 2.3, 2.4,1, 2.4. All have the same result.. Here the code snippets of my configuration:
我 100% 确定我的方法被调用了。该方法中的 System.out.println 显示在控制台中,我的 Eclipse 调试器清楚地通过了设置的断点。我是否使用 Jersey 2.0、2.3、2.4、1、2.4 并不重要。都有相同的结果..这里是我的配置的代码片段:
StartJetty.java:
StartJetty.java:
final int mainport = 9123;
Server jettyServer = new Server(mainport);
HandlerCollection handlerCollection = new ContextHandlerCollection();
jettyServer.setHandler(handlerCollection);
ServletHolder jerseyServlet = context.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/");
jerseyServlet.setInitOrder(1);
jerseyServlet.setInitParameter("jersey.config.server.provider.packages", "com.test.rest");
handlerCollection.addHandler(context);
jettyServer.start();
jettyServer.join();
Snippet from the REST resource:com.test.rest.PersonsRSImpl.class:
来自 REST 资源的片段:com.test.rest.PersonsRSImpl.class:
@Path("/persons")
@Produces( MediaType.APPLICATION_JSON)
public class PersonsRSImpl {
private PersonManager personMgr = PersonManager.getInstance();
@Path("/list")
public Collection<Person> list() {
System.out.println("In Person::list" );
return personMgr.getPersons();
}
}
My Person object is a simple POJO, with some JAXB annotations. Adding/removing them makes no difference at all.
我的 Person 对象是一个简单的 POJO,带有一些 JAXB 注释。添加/删除它们根本没有区别。
Last but not least: pom.xmlhttp://maven.apache.org/maven-v4_0_0.xsd">
最后但并非最不重要的: pom.xmlhttp://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>integrationexample</artifactId>
<packaging>jar</packaging>
<version>1.0.0-SNAPSHOT</version>
<name>Test project</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.outputEncoding>UTF-8</project.build.outputEncoding>
<jetty.version>7.5.4.v20111024</jetty.version>
<jersey.version>2.4.1</jersey.version>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-http-spi</artifactId>
<version>${jetty.version}</version>
</dependency>
<!-- Jersey JAX-RS -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-simple-http</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.test.StartJetty</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
I enabled a trace of Jersey (thank you Michal). The result trace is:
我启用了一点泽西(谢谢 Michal)。结果跟踪是:
Jersey trace
泽西岛痕迹
HTTP/1.1 404 Not Found
X-Jersey-Tracing-000: START [ ---- / ---- ms | ---- %] baseUri=[http://localhost:9123/rest/] requestUri=[http://localhost:9123/rest/persons/list] method=[GET] authScheme=[n/a] accept=[text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8] accept-encoding=[gzip, deflate] accept-charset=n/a accept-language=[en-US,en;q=0.5] content-type=n/a content-length=n/a
X-Jersey-Tracing-001: PRE-MATCH [ 0,01 / 1,03 ms | 0,10 %] PreMatchRequest summary: 0 filters
X-Jersey-Tracing-002: MATCH [ ---- / 1,21 ms | ---- %] Matching path [/persons/list]
X-Jersey-Tracing-003: MATCH [ ---- / 1,27 ms | ---- %] Pattern [/persons(/.*)?] IS selected
X-Jersey-Tracing-004: MATCH [ ---- / 1,41 ms | ---- %] Matched resource: template=[/persons] regexp=[/persons(/.*)?] matches=[/persons] from=[/persons/list]
X-Jersey-Tracing-005: MATCH [ ---- / 1,54 ms | ---- %] Matching path [/list]
X-Jersey-Tracing-006: MATCH [ ---- / 1,58 ms | ---- %] Pattern [/list(/.*)?] IS selected
X-Jersey-Tracing-007: MATCH [ ---- / 1,76 ms | ---- %] Matched resource: template=[/list] regexp=[/list(/.*)?] matches=[/list] from=[/list]
X-Jersey-Tracing-008: MATCH [ ---- / 1,90 ms | ---- %] Matched locator : public java.util.Collection com.test.rest.PersonsRSImpl.list()
X-Jersey-Tracing-009: MATCH [ ---- / 2,08 ms | ---- %] Resource instance: [com.test.rest.PersonsRSImpl @3cceafcb]
X-Jersey-Tracing-010: MATCH [ ---- / 2,21 ms | ---- %] Resource instance: [java.util.HashMap$Values @25591d82]
X-Jersey-Tracing-011: MATCH [ 4,23 / 5,30 ms | 75,92 %] RequestMatching summary
X-Jersey-Tracing-012: RESP-FILTER [ 0,00 / 5,52 ms | 0,05 %] Response summary: 0 filters
X-Jersey-Tracing-013: FINISHED [ ---- / 5,58 ms | ---- %] Response status: 404/CLIENT_ERROR|Not Found
Cache-Control: must-revalidate,no-cache,no-store
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 1284
Server: Jetty(7.5.4.v20111024)
Hope some of you have a clue on what's going on!
希望你们中的一些人知道发生了什么!
采纳答案by Michal Gajdos
You need to annotate your resource method list()
with an annotation that would indicate to which HTTP method should the resource method respond to (in this case it would be @GET):
您需要使用注释来注释您的资源方法list()
,该注释将指示资源方法应响应哪个 HTTP 方法(在本例中为@GET):
@GET
@Path("/list")
public Collection<Person> list() {
System.out.println("In Person::list" );
return personMgr.getPersons();
}
Otherwise the resource method would be invoked but it will be treated as sub-resource locator. For more information about sub-resources and sub-resource locators refer to the JAX-RS 2.0 specor Jersey User Guide dedicated to Sub-resources.
否则资源方法将被调用,但它将被视为子资源定位器。有关子资源和子资源定位器的更多信息,请参阅JAX-RS 2.0 规范或 Jersey 用户指南,专门用于子资源。