Какой init-param использовать: jersey.config.server.provider.packages или javax.ws.rs.Application?

Я развертываю веб-службы JAX-RS в контейнере сервлетов Tomcat.

Я видел примеры кода, которые используют один из следующих двух способов указания ресурсов в файле web.xml:

метод 1 - с помощью `jersey.config.server.provider.packages` init-param

  <servlet>
      <servlet-name>Jersey Web Application</servlet-name>
      <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
      <init-param>
          <param-name>jersey.config.server.provider.packages</param-name>
          <param-value>com.example</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
  </servlet>

... где ожидается, что ресурсы будут находиться в пакете com.example, и я предполагаю, что они обнаружены с помощью Java RTTI.

метод 2 - с помощью `javax.ws.rs.Application` init-param

<servlet>
 <servlet-name>jersey-serlvet</servlet-name>
 <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
   <init-param>
           <param-name>javax.ws.rs.Application</param-name>
           <param-value>full.qualified.name.to.MyApplication</param-value>
   </init-param>
 <load-on-startup>1</load-on-startup>
</servlet> 

... где класс MyApplication явно идентифицирует классы ресурсов:

public class MyApplication extends javax.ws.rs.core.Application {
   public Set<Class<?>> getClasses() {
      Set<Class<?>> s = new HashSet<Class<?>>();
      s.add(ResourceA.class);
      return s;
}

Использует один и тот же метод, исключительно вопрос вкуса и конфигурации, и каковы некоторые компромиссы? Лично я предпочитаю более мелкозернистый контроль, предлагаемый методом 2, однако архетип maven Jersey 2.7:

mvn archetype:generate -DarchetypeArtifactId=jersey-quickstart-webapp \
            -DarchetypeGroupId=org.glassfish.jersey.archetypes -DinteractiveMode=false \
            -DgroupId=com.example -DartifactId=simple-service-webapp -Dpackage=com.example \
            -DarchetypeVersion=2.7

... использует метод 1, и это заставило меня задуматься.

Ответ 1

Способ 1 (с использованием параметра init init сервлета jersey.config.server.provider.packages): специфический для Джерси и выглядит только в пакетах. Он не переносится между различными реализациями JAX-RS. Вы можете использовать его в сценариях, если хотите ограничить рассмотренные классы/приложения ресурса JAX-RS.

Способ 2 (с использованием сервлета init param javax.ws.rs.Application): любая реализация JAX-RS ДОЛЖНА поддерживать этот вариант развертывания, таким образом переносимый (хотя, если вы переключитесь на другую реализацию JAX-RS, такую ​​как RestEasy, вам придется изменить класс сервлета). Этот параметр предлагает больше детализации (вы можете выбрать именно классы для рассмотрения, а не только целые пакеты). Недостаток: вам нужно написать больше кода.

Способ 3 (в контейнере 3 сервлетов, где вы, вероятно, уже развернули): определение только ваших приложений JAX-RS без каких-либо сервлетов (проверьте Развертывание с использованием дескриптора web.xml), вероятно, является лучшим способом (он также переносим между реализациями JAX-RS и вы можете изменить реализацию JAX-RS без изменения в web.xml), если у вас явно объявлен JAX Приложение -RS (которое у вас есть).

Способ 4 Если вы хотите развернуть все классы из вашего военного архива в контейнере 3 сервлетов (без явно заданного приложения JAX-RS), вы можете сделать это также переносимым образом. Проверьте это здесь: Приложение JAX-RS без подкласса Application