如何仅使用注释来设置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
问题
-
为什么web.xml定义起作用,但注释没有? 有什么不同?
-
有没有办法让它工作,例如有没有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.xml
configuration任何东西(或者根本没有):
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