是否可以仅使用注释来设置 JAX-RS 应用程序?(使用 Servlet 3.0 和 JAX-RS Jersey 1.1.0(
我试过了,没有运气。使用一些web.xml
似乎是必需的。
配置
A(工作正常,但具有 Web.xml 配置(
网络.xml
...
<servlet>
<servlet-name>org.foo.rest.MyApplication</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>org.foo.rest.MyApplication</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
...
爪哇岛
@ApplicationPath("/")
public class MyApplication extends Application {
...
}
配置 B(不工作,引发异常(
@ApplicationPath("/")
@WebServlet("/*") // <--
public class MyApplication extends Application {
...
}
后者似乎坚持认为应用程序将是 Servlet 的一个子类(例外没有留下任何猜测(
java.lang.ClassCastException: org.foo.rest.MyApplication cannot be cast to javax.servlet.Servlet
问题
为什么网络.xml定义有效,但注释不起作用?有什么区别?
有没有办法让它工作,例如,有一个没有网络.xml的 JAX-RS 应用程序?
** 如果您使用TOMCAT或JETTY,请阅读
! **接受的答案确实有效,但前提是将Web应用程序部署到像Glassfish或Wildfly这样的应用程序服务器,以及可能具有EE扩展的servlet容器,如TomEE。它不适用于像Tomcat这样的标准servlet容器,我相信大多数在这里寻找解决方案的人都想使用它。
如果您使用的是标准的Tomcat安装(或其他一些servlet容器(,则需要包含REST实现,因为Tomcat没有附带一个。如果您使用的是 Maven,请将其添加到dependencies
部分:
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.bundles</groupId>
<artifactId>jaxrs-ri</artifactId>
<version>2.13</version>
</dependency>
...
</dependencies>
然后只需将应用程序配置类添加到项目中即可。如果除了为其余服务设置上下文路径之外没有任何特殊配置需求,则该类可以为空。添加此类后,您无需在 web.xml
中配置任何内容(或根本没有一个(:
package com.domain.mypackage;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("rest") // set the path to REST web services
public class ApplicationConfig extends Application {}
在此之后,使用 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);
}
}
这应该是您所需要的。如果您的 Tomcat 安装在端口 8080 上本地运行,并且您将 WAR 文件部署到上下文myContext
,将...
http://localhost:8080/myContext/rest/calc/1.0/addTwoNumbers;firstNumber=2;secondNumber=3
。应产生预期结果(5(。
看来我需要做的就是这个(Servlet 3.0 及更高版本(
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("/*")
public class MyApplication extends Application {
...
}
显然不需要网络.xml配置(在Tomcat 7上尝试(
JAX-RS:Java™ API for RESTful Web Services 规范的第 2 章描述了 JAX-RS 应用程序在 Servlet 环境中的发布过程(规范中的 2.3.2 节 Servlet(。
请注意,仅建议使用 Servlet 3 环境(第 2.3.2 节 Servlet,第 6 页(:
建议实现支持 Servlet 3 框架可插拔性机制,以实现 容器并利用容器提供的类 扫描设施。
简而言之,如果你想使用一种无web.xml的方法,可以使用javax.ws.rs.core.Application的自定义实现,该实现使用javax.ws.rs.ApplicationPath注释注册RESTful服务资源。
@ApplicationPath("/rest")
虽然您特别询问了有关 Jersey 的问题,但您可能还想阅读文章使用 JAX-RS 和 WebSphere 8.5 Liberty Profile 实现 RESTful 服务,其中我描述了 WebSphere Liberty Profile 的无 web.xml 发布过程(使用 Apache Wink 作为 JAX-RS 的实现(。
您需要在 pom 中设置正确的依赖项.xml
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
</dependency>
更多细节在这里:jax-rs 的入门示例
前面提到的依赖项对我不起作用。来自泽西岛用户指南:
Jersey 提供了两个 Servlet 模块。第一个模块是 Jersey 核心 Servlet 模块,它提供核心 Servlet 集成支持,在任何 Servlet 2.5 或更高版本的容器中都是必需的:
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
</dependency>
要支持其他 Servlet 3.x 部署模式和异步 JAX-RS 资源编程模型,需要一个额外的 Jersey 模块:
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
</dependency>
jersey-container-servlet 模块依赖于 jersey-container-servlet-core模块,因此在使用时,没有必要显式声明 jersey-container-servlet-core 依赖关系。
https://jersey.github.io/documentation/latest/deployment.html#deployment.servlet.3
正如棉兰@Eran指出的那样,JBoss EAP 7.1(注意没有Web应用程序,所以没有servlet,我在EJB 3.2项目中这样做(我必须添加"value"属性,因为我得到了一个异常,需要值属性。
这对我有用
@ApplicationPath(value="/*")
public class MyApplication extends Application {
private Set singletons = new HashSet();
public MyApplication() {
singletons.add(new MyService());
}
...
}
堆栈跟踪
Caused by: java.lang.annotation.IncompleteAnnotationException: javax.ws.rs.ApplicationPath missing element value
at sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:80)
at com.sun.proxy.$Proxy141.value(Unknown Source)
... 21 more