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

Java 如何仅使用注释(无web.xml)设置JAX-RS应用程序?,java,jakarta-ee,jax-rs,servlet-3.0,Java,Jakarta Ee,Jax Rs,Servlet 3.0,是否可以仅使用注释来设置JAX-RS应用程序?(使用Servlet3.0和JAX-RS1.1.0) 我试过了,但运气不好。似乎需要使用一些web.xml 配置A(工作,但具有web.xml配置) web.xml 。。。 org.foo.rest.MyApplication org.foo.rest.MyApplication /* ... 爪哇 配置B(不工作,引发异常) 问题 为什么web.xml定义有效,而注释无效?有什么区别 有没有一种方法可以让它工作,例如,有一个没有web.xm

是否可以仅使用注释来设置JAX-RS应用程序?(使用Servlet3.0和JAX-RS1.1.0)

我试过了,但运气不好。似乎需要使用一些
web.xml


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

web.xml

。。。
org.foo.rest.MyApplication
org.foo.rest.MyApplication
/*
...
爪哇


配置B(不工作,引发异常)


问题

  • 为什么web.xml定义有效,而注释无效?有什么区别

  • 有没有一种方法可以让它工作,例如,有一个没有web.xml的JAX-RS应用程序


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

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

    本规范第2章描述了Servlet环境中JAX-RS应用程序的发布过程(本规范第2.3.2节Servlet)

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

    建议实现支持Servlet 3 框架可插拔性机制,可在 容器,并利用容器提供的类别 扫描设备

    简而言之,如果您想使用no-web.xml方法,可以使用的自定义实现将RESTful服务资源注册到注释中

    @ApplicationPath("/rest")
    

    尽管您特别询问了Jersey的情况,但您可能也喜欢阅读我在文章中描述的no-web.xml发布过程(使用ApacheWink作为JAX-RS的实现)。

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

    接受的答案确实有效,但只有当webapp部署到Glassfish或Wildfly等应用服务器上,并且可能部署到带有EE扩展的servlet容器(如TomEE)上时,才有效。它不适用于像Tomcat这样的标准servlet容器,我相信在这里寻找解决方案的大多数人都想使用它

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

    
    org.glassfish.jersey.bundles
    杰克斯里
    2.13
    ...
    
    然后只需向项目中添加一个应用程序配置类。如果除了为rest服务设置上下文路径之外,您没有任何特殊的配置需要,那么该类可以为空。添加此类后,您不需要在
    web.xml
    中配置任何内容(或者根本不需要配置任何内容):

    在此之后,在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;第二个数字=3
    

    …应产生预期结果(5)。

    您需要在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>
    
    
    javax.servlet
    

    正如@Eran Medan指出的,JBoss EAP 7.1(注意,没有Web应用程序,所以没有servlet,我是在EJB3.2项目中进行的)我必须添加“value”属性,因为我得到了一个需要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

    前面提到的依赖项对我不起作用。从泽西岛用户指南:

    Jersey提供了两个Servlet模块。第一个模块是Jersey core Servlet模块,它提供核心Servlet集成支持,在任何Servlet 2.5或更高版本的容器中都是必需的:

    
    org.glassfish.jersey.containers
    

    如果您可以尝试使用NetBeans,那么有一个创建RESTFul web服务的向导。看起来您正试图做的就是这个向导在6.8版中所做的。我使用的是7.0.1,新方法更简单,但使用了一个servlet,即com.sun.jersey.spi.container.servlet.ServletContainer,但它是在web.xmlThank中定义的!,我还有另一个让我发疯的问题,有没有办法让路径在根目录中(例如@ApplicationPath(“/*”),并且仍然只使用注释为JSP服务?(虽然即使使用web.xml配置,我也无法做到这一点)-问题是:,因为您似乎非常了解JAX-RS,请您看一看好吗?:)也许你会看到我错过了什么。。。谢谢我不知道。直觉告诉我,它不需要额外的配置,因为解析资源以处理请求的过程是从与URL模式完全匹配的过程。我看一下,然后回答。谢谢你鼓励我扩展知识!:-)我使用
    @ApplicationPath(“”
    在JBoss EAP 7上的根目录(相对于webapp上下文根目录)中拥有我的REST服务。我既没有
    beans.xml
    也没有
    web.xml
    。不明白这是如何工作的,您只能使用注释而不需要任何其他配置?我试过这样做,但仍然不起作用…@Filipe:我猜你在使用Tomcat或其他servlet容器。这实际上不适用于像Tomcat这样的servlet容器——它只适用于像Glassfish或Wildfly这样的应用服务器,可能还有TomEE。如果您正在使用Tomcat,请参阅下面我的(迟交的)答案。此答案不适用于Tomcat或Jetty!请参阅我的答案,以便在这些(和其他)servlet容器中工作。根据您的实现,您确实需要一个web.xml,尽管一个空的就足够了。请参阅,这适用于WebSphereLiberty,但不适用于WebSphere8.x和9.0
    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 {}
    
    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);
      }
    }
    
    <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>
    
        @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
    <dependency>
     <groupId>org.glassfish.jersey.containers</groupId>
     <artifactId>jersey-container-servlet-core</artifactId>
    </dependency>
    
    <dependency>
     <groupId>org.glassfish.jersey.containers</groupId>
     <artifactId>jersey-container-servlet</artifactId>
    </dependency>