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

Era*_*dan 76 java jax-rs java-ee servlet-3.0

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

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


配置A(工作,但具有web.xml配置)

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>
   ...
Run Code Online (Sandbox Code Playgroud)

Java的

@ApplicationPath("/")
public class MyApplication extends Application {
    ...
}
Run Code Online (Sandbox Code Playgroud)

配置B(不工作,抛出异常)

@ApplicationPath("/")
@WebServlet("/*") // <-- 
public class MyApplication extends Application {
    ...
}
Run Code Online (Sandbox Code Playgroud)

后者似乎坚持认为Application将是Servlet的子类(例外不会留下任何猜测)

java.lang.ClassCastException: org.foo.rest.MyApplication cannot be cast to javax.servlet.Servlet
Run Code Online (Sandbox Code Playgroud)

问题

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

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

Alv*_*son 159

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

接受的答案确实有效,但前提是将webapp部署到像Glassfish或Wildfly这样的应用服务器,以及可能的部署了像TomEE这样的EE扩展的servlet容器.它不适用于像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>
Run Code Online (Sandbox Code Playgroud)

然后只需将应用程序配置类添加到项目中.如果除了为其余服务设置上下文路径之外没有任何特殊配置需求,则该类可以为空.添加此类后,您无需配置任何内容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 {}
Run Code Online (Sandbox Code Playgroud)

在此之后,使用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);
  }
}
Run Code Online (Sandbox Code Playgroud)

这应该是你所需要的.如果您的Tomcat安装在端口8080上本地运行,并且您将WAR文件部署到上下文myContext,则转到...

http://localhost:8080/myContext/rest/calc/1.0/addTwoNumbers;firstNumber=2;secondNumber=3
Run Code Online (Sandbox Code Playgroud)

......应该产生预期的结果(5).

  • @JavaDude - 重要的部分是`<failOnMissingWebXml> false </ fai lOnMissingWebXml>`选项. (6认同)
  • @JavaDude - 你必须配置Maven来构建WAR文件,即使`web.xml`不存在.在你的`pom.xml`中,在"build> plugins"下,添加(如果还没有):`<plugin> <groupId> org.apache.maven.plugins </ groupId> <artifactId> maven-war-plugin < /artifactId><version>2.3</version><configuration><failOnMissingWebXml>false</failOnMissingWebXml> </配置> </插件>`. (4认同)
  • 仅添加`jersey-container-servlet`就足够了,而不会拉动整个`jaxrs-ri`依赖.例如,在我的情况下,它是''org.glassfish.jersey.core:jersey-server:2.18'`+`'org.glassfish.jersey.containers:jersey-container-servlet:2.18'`. (3认同)
  • 由于这个问题清楚地用"java-ee"标记,我不明白提供和提出一个不解决jee环境的答案的模糊.-1 (3认同)
  • @ alvin-thompson你是如何建立战争的?因为我有一个例外=====组装WAR时出错:需要webxml属性(如果在更新模式下执行,则预先存在的WEB-INF/web.xml) - > [帮助1] (2认同)
  • @JavaDude-如果不是,您可能没有创建扩展`Application`的类并向其中添加`@ ApplicationPath`注释。该类可以为空,但必须存在。 (2认同)
  • @JanGalinski:我不确定这是什么困惑。甚至标准版本的Tomcat都实现了Java EE Web概要文件。这确实是Java EE。 (2认同)

Era*_*dan 48

似乎所有我需要做的就是这个(Servlet 3.0及以上版本)

@ApplicationPath("/*")
public class MyApplication extends Application {
    ...
}
Run Code Online (Sandbox Code Playgroud)

并且显然不需要web.xml配置(在Tomcat 7上试过)

  • **这个答案不适用于Tomcat或Jetty!**请参阅我的答案,以便在那些(和其他)servlet容器中工作. (8认同)
  • 不完全正确.它至少适用于Tomcat 7 (7认同)
  • @Filipe:我猜你正在使用Tomcat或其他一些servlet容器.这实际上不适用于像Tomcat这样的servlet容器 - 它只适用于像Glassfish或Wildfly这样的应用服务器,也可能适用于TomEE.如果您正在使用Tomcat,请参阅下面的我(后期)答案. (2认同)

Jac*_*ski 14

JAX-RS的第2章:用于RESTful Web服务的Java™API规范描述了Servlet环境中JAX-RS应用程序的发布过程(规范中的2.3.2Servlet).

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

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

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

@ApplicationPath("/rest")
Run Code Online (Sandbox Code Playgroud)

虽然您特别询问了Jersey,但您也可以阅读文章使用JAX-RS和WebSphere 8.5 Liberty Profile实现RESTful服务,其中我描述了WebSphere Liberty Profile的no-web.xml发布过程(使用Apache Wink作为实现JAX-RS).


ACV*_*ACV 6

您需要在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>
Run Code Online (Sandbox Code Playgroud)

这里有更多细节: jax-rs的入门示例