如何仅使用注释来设置JAX-RS应用程序(无web.xml)?

是否可以使用注释来设置JAX-RS应用程序? (使用Servlet 3.0和JAX-RS Jersey 1.1.0)

我试过,没有运气。 似乎需要使用一些web.xml


configurationA(正在工作,但有web.xmlconfiguration)

web.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> ... 

Java的

 @ApplicationPath("/") public class MyApplication extends Application { ... } 

configurationB(不工作,抛出exception)

 @ApplicationPath("/") @WebServlet("/*") // <-- public class MyApplication extends Application { ... } 

后者似乎坚持认为,应用程序将是一个Servlet的子类(这个例外没有猜测)

 java.lang.ClassCastException: org.foo.rest.MyApplication cannot be cast to javax.servlet.Servlet 

问题

  1. 为什么web.xml定义起作用,但注释没有? 有什么不同?

  2. 有没有办法让它工作,例如有没有web.xml的JAX-RS应用程序?

**请阅读如果您使用TOMCAT或JETTY! **

接受的答案有效的,但是只有当webapp被部署到像Glassfish或Wildfly这样的应用服务器,并且可能还有像TomEE这样的EE扩展的servlet容器。 它不适用于像Tomcat这样的标准servlet容器,我相信大多数人在寻找解决scheme的时候都想使用它。

如果您使用的是标准的Tomcat安装(或其他一些servlet容器),那么您需要包含一个REST实现,因为Tomcat不附带一个。 如果您使用的是Maven,请将其添加到dependencies部分:

 <dependencies> <dependency> <groupId>org.glassfish.jersey.bundles</groupId> <artifactId>jaxrs-ri</artifactId> <version>2.13</version> </dependency> ... </dependencies> 

然后只需将一个应用程序configuration类添加到您的项目。 如果除了为其余服务设置上下文path之外,没有任何特殊的configuration需求,则该类可以为空。 一旦添加了这个类,就不需要在web.xmlconfiguration任何东西(或者根本没有):

 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及以上)

 @ApplicationPath("/*") public class MyApplication extends Application { ... } 

并没有明显需要web.xmlconfiguration(尝试在Tomcat 7)

JAX-RS的第2章:用于REST风格的Web服务的Java™API规范描述了在Servlet环境中的JAX-RS应用程序的发布过程(规范中的2.3.2小节)。

请注意,仅build议使用Servlet 3环境(第2.3.2节Servlet,第6页):

build议实现支持Servlet 3框架可插入性机制,以实现容器之间的可移植性,并利用容器提供的类扫描工具。

简而言之,如果您想使用no-web.xml方法,则可以使用javax.ws.rs.core.Application的自定义实现来注册带有javax.ws.rs.ApplicationPath注释的RESTful服务资源。

 @ApplicationPath("/rest") 

尽pipe您特别提到了Jersey,但您也可以阅读使用JAX-RS和WebSphere 8.5 Liberty Profile实现RESTful服务的文章,其中描述了WebSphere Liberty Profile的no-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的入门示例

正如@Eran-Medan指出的,JBoss EAP 7.1(注意没有Web应用程序,所以没有servlet,我是在EJB 3.2项目中做的),我不得不添加“value”属性,因为我得到一个exception值属性是必需的。

这对我有效

  @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