Как настроить приложение JAX-RS, используя только annotations (без web.xml)?

Можно ли настроить приложение JAX-RS только с помощью аннотаций? (с использованием Servlet 3.0 и JAX-RS Jersey 1.1.0)

Я попробовал и не повезло. Использование некоторого web.xml кажется необходимым.


Конфигурация A (рабочая, но имеет конфигурацию web.xml)

web.xml

  ...  org.foo.rest.MyApplication   org.foo.rest.MyApplication /*  ... 

Ява

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

Конфигурация B (не работает, исключение выбрано)

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

Последнее, похоже, настаивает на том, что приложение будет подclassом Servlet (исключение не оставляет догадок)

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

Вопросов

  1. Почему работало определение web.xml, но annotations не было? Какая разница?

  2. Есть ли способ заставить его работать, например, иметь приложение JAX-RS без web.xml?

    ** ПОЖАЛУЙСТА, ЧИТАЙТЕ, ЕСЛИ ВЫ ИСПОЛЬЗУЕТЕ ТОМКАТ ИЛИ ЖЕСТКО! **

    Принятый ответ работает, но только если webapp развернут на сервер приложений, например Glassfish или Wildfly, и, возможно, контейнеры сервлетов с расширениями EE, такими как TomEE. Он не работает в стандартных контейнерах сервлетов, таких как Tomcat, и я уверен, что большинство людей, которые ищут решение здесь, хотят использовать.

    Если вы используете стандартную установку Tomcat (или какой-либо другой контейнер сервлета), вам необходимо включить реализацию REST, поскольку Tomcat не поставляется с одним. Если вы используете Maven, добавьте это в раздел dependencies :

       org.glassfish.jersey.bundles jaxrs-ri 2.13  ...  

    Затем просто добавьте в свой проект class конфигурации приложения. Если у вас нет каких-либо особых потребностей в настройке, кроме настройки контекстного пути для остальных служб, class может быть пустым. Как только этот class добавлен, вам не нужно ничего настраивать в 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 {} 

    После этого объявление ваших веб-сервисов выполняется с использованием стандартных аннотаций JAX-RS в ваших Java-classах:

     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.xml, по-видимому, не было (опробован на Tomcat 7)

    В главе 2 спецификации JAX-RS: Java ™ API для RESTful Web Services описывается процесс публикации приложения JAX-RS в среде Servlet (раздел 2.3.2 Servlet в спецификации).

    Обратите внимание, что рекомендуется использовать среду Servlet 3 (раздел 2.3.2 Servlet, стр. 6):

    РЕКОМЕНДОВАНО, что реализации поддерживают механизм совместимости фреймворка Сервлета 3, чтобы обеспечить переносимость между контейнерами и воспользоваться возможностями сканирования classа контейнера.

    Короче говоря, если вы хотите использовать подход no-web.xml, это возможно с помощью специальной реализации javax.ws.rs.core.Application, которая регистрирует ресурсы службы RESTful с помощью annotations javax.ws.rs.ApplicationPath .

     @ApplicationPath("/rest") 

    Хотя вы спросили конкретно о Джерси, вам также может понравиться прочитать статью « Реализация услуг RESTful с помощью JAX-RS и WebSphere 8.5 Liberty Profile», в которой я описал процесс публикации no-web.xml для профиля WebSphere Liberty (с Apache Wink в качестве реализации JAX-RS).

    Вам нужно настроить правильные зависимости в pom.xml

      javax.servlet javax.servlet-api 3.0.1 provided   org.glassfish.jersey.containers jersey-container-servlet  при  javax.servlet javax.servlet-api 3.0.1 provided   org.glassfish.jersey.containers jersey-container-servlet  ,  javax.servlet javax.servlet-api 3.0.1 provided   org.glassfish.jersey.containers jersey-container-servlet  

    Подробнее здесь: Пример стартера для jax-rs

    Как отметил Эран-Медан, JBoss EAP 7.1 (обратите внимание, что без веб-приложения, без сервлета, я делал это в проекте 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 

    Ранее упомянутые зависимости не работали для меня. Из руководства пользователя Jersey:

    Джерси предоставляет два модуля Servlet. Первым модулем является модуль ядра Servlet, который обеспечивает базовую поддержку интеграции сервлетов и требуется в любом контейнере Servlet 2.5 или выше:

      org.glassfish.jersey.containers jersey-container-servlet-core  

    Для поддержки дополнительных режимов развертывания Servlet 3.x и асинхронной модели программирования ресурсов JAX-RS требуется дополнительный модуль Джерси:

      org.glassfish.jersey.containers jersey-container-servlet  

    Модуль jersey-container-servlet зависит от модуля ядра jersey-container-servlet-core, поэтому, когда он используется, нет необходимости явно объявлять зависимость jersey-container-servlet-core.

    https://jersey.github.io/documentation/latest/deployment.html#deployment.servlet.3

    Давайте будем гением компьютера.