Java 为什么这个简单的 JAX RS 示例不起作用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20813767/
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
Why is this Simple JAX RS example not working?
提问by Fagner Brack
I am trying to get working a simple JAX RS example, but I am failing to do so.
我正在尝试使用一个简单的 JAX RS 示例,但我没有这样做。
web.xml
网页.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:jsp="http://java.sun.com/xml/ns/javaee/jsp" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>PLAYGROUND</display-name>
<servlet-mapping>
<servlet-name>playground.Rest</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
</web-app>
Rest.java
REST.java
package playground;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Application;
public class Rest extends Application {
@GET
@Path("hello")
public String helloworld() {
return "Hello World!";
}
}
Accessing http://localhost/{warcontext}/api/hello
with the browser (GET) gives me 404 error status
http://localhost/{warcontext}/api/hello
使用浏览器 (GET)访问给我 404 错误状态
It is probably something very silly but I can't figure out.
这可能是非常愚蠢的事情,但我无法弄清楚。
Using: JBoss EAP 6.1.0 (Java EE 6)
使用:JBoss EAP 6.1.0 (Java EE 6)
采纳答案by Xavier Coulon
You need to extend javax.ws.rs.core.Application (it can remain empty) and annotate it with @ApplicationPath("/ide"), then create a JAX-RS resource, ie, a class with an @Path("/hello") annotation. In this class, you'll just need to have your JAX-RS Resource Method annotated with @GET.
您需要扩展javax.ws.rs.core.Application(它可以保持为空)并使用@ApplicationPath("/ide") 对其进行注释,然后创建一个JAX-RS 资源,即一个带有@Path(" /hello") 注释。在本课程中,您只需要使用 @GET 注释您的 JAX-RS 资源方法。
@ApplicationPath("/ide")
public class Rest extends Application { }
@Path("/hello")
public class HelloResource {
@GET
@Path("hello")
public String helloworld() {
return "Hello World!";
}
}
You can also take a look at this example: https://github.com/resteasy/Resteasy/tree/master/jaxrs/examples/oreilly-workbook/ex03_1
你也可以看看这个例子:https: //github.com/resteasy/Resteasy/tree/master/jaxrs/examples/oreilly-workbook/ex03_1
回答by Stephane Lallemagne
You need to declare servlet-class in web.xml(servlet name is not the same):
需要在web.xml中声明servlet-class (servlet名称不一样):
<servlet>
<servlet-name>Playground REST services</servlet-name>
<servlet-class>your.package.playground.Rest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Playground REST services</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
Use the full name of your class (including package path name) in servlet-class.
在 servlet-class 中使用您的类的全名(包括包路径名)。
回答by Qwertovsky
web.xml
网页.xml
<servlet>
<servlet-name>RestServlet</servlet-name>
<servlet-class>javax.ws.rs.core.Application</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RestServlet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
Rest.java
REST.java
public class Rest {
@GET
@Path("hello")
public String helloworld() {
return "Hello World!";
}
}
If you need, you can add
如果需要,您可以添加
YourApplication.java
你的应用程序
package playground;
import javax.ws.rs.core.Application;
...
public class YourApplication extends Application {
@Override
public Set<Class<?>> getClasses()
{
Set<Class<?>> yourResources = new HashSet<Class<?>>();
yourResources.add(InvoiceResource.class);
return yourResources;
}
}
Then
然后
web.xml
网页.xml
<servlet>
<servlet-name>RestServlet</servlet-name>
<servlet-class>playground.YourApplication</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RestServlet</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
If you add @ApplicationPath("/api")
for YouApplication
, then web.xml shouldn't have servlet-mapping
.
如果添加@ApplicationPath("/api")
for YouApplication
,则 web.xml 不应包含servlet-mapping
。
回答by Alvin Thompson
I also had issues getting this to work, so I'm posting a more complete how-to for posterity:
我也遇到了让它工作的问题,所以我为后代发布了一个更完整的操作方法:
If you're using a standard Tomcat install (or some other servlet container), AFAIK you can't avoid explicitly telling it what servlets to start in the web.xml
file*. Since you have to use web.xml
anyway, the simplest way to get restful web services working is to forget extending javax.ws.rs.core.Application
entirely and just specify the context path there. You can still use standard jax-rs annotations to declare the actual web services.
如果您使用标准的 Tomcat 安装(或其他一些 servlet 容器),AFAIK 您无法避免明确告诉它在web.xml
文件中启动哪些 servlet *。由于web.xml
无论如何您都必须使用,因此让 Restful Web 服务工作的最简单方法是javax.ws.rs.core.Application
完全忘记扩展并在那里指定上下文路径。您仍然可以使用标准的 jax-rs 注释来声明实际的 Web 服务。
web.xml:
网页.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
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_3_0.xsd"
version="3.0"
>
<servlet>
<servlet-name>rest-test</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.domain.mypackage</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name> rest-test</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
Two noteworthy points:
值得注意的两点:
You will need to bundle a REST implementation in your WAR file, since servlet containers don't usually contain one. Since Jersey is the reference implementation for JAX-RS, that's the one I'm using in the
servlet-class
element above. You can replace this with Apache CXF implementation if you want.The
init-param
element tells Jersey which of your packages to search for Java files with web service annotations. Edit this to point to your web services. Note that if you opt to use apache CXF instead of Jersey, the stuff needed in anyinit-param
elements will be different. Someone who knows CXF please post what they would be.
您需要在 WAR 文件中捆绑 REST 实现,因为 servlet 容器通常不包含一个。由于 Jersey 是 JAX-RS 的参考实现,因此我在
servlet-class
上面的元素中使用了它。如果需要,您可以将其替换为 Apache CXF 实现。该
init-param
元素告诉 Jersey 使用 Web 服务注释搜索您的哪些包来搜索 Java 文件。编辑它以指向您的 Web 服务。请注意,如果您选择使用 apache CXF 而不是 Jersey,则任何init-param
元素中所需的内容都会有所不同。知道CXF的人请发布他们会是什么。
If you're using Maven, just add a dependency to jersey-servlet
in the dependencies
section of your pom.xml
file:
如果您使用 Maven,只需jersey-servlet
在dependencies
您的pom.xml
文件部分添加一个依赖项:
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.18.2</version>
</dependency>
...
</dependencies>
After this, declaring your web services is straight forward using the standard JAX-RS annotations in your Java classes:
在此之后,使用 Java 类中的标准 JAX-RS 注释直接声明您的 Web 服务:
package com.domain.mypackage;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.GET;
import javax.ws.rs.MatrixParam;
import javax.ws.rs.Path;
// It's good practice to include a version number in the path so you can have
// multiple versions deployed at once. That way consumers don't need to upgrade
// right away if things are working for them.
@Path("calc/1.0")
public class CalculatorV1_0 {
@GET
@Consumes("text/plain")
@Produces("text/plain")
@Path("addTwoNumbers")
public String add(@MatrixParam("firstNumber") int n1, @MatrixParam("secondNumber") int n2) {
return String.valueOf(n1 + n2);
}
}
This should be all you need. If your Tomcat install is running locally on port 8080 and you deploy your WAR file to the context myContext
, going to
这应该就是你所需要的。如果您的 Tomcat 安装在端口 8080 上本地运行,并且您将 WAR 文件部署到上下文myContext
,则转到
http://localhost:8080/myContext/rest/calc/1.0/addTwoNumbers;firstNumber=2;secondNumber=3
...should produce the expected result (5).
...应该产生预期的结果 (5)。
Cheers!
干杯!
* Someone please correct me if you know of a way to a add the Jersey servlet to the context in Tomcat without using web.xml
--maybe by using a context or life cycle listener?
* 如果您知道一种将 Jersey servlet 添加到 Tomcat 中的上下文而不使用web.xml
--maybe 使用上下文或生命周期侦听器的方法,请纠正我?