使用哪个初始化参数:jersey.config.server.provider.packages 或 javax.ws.rs.Application?

2022-01-21 00:00:00 web-services java tomcat jax-rs jersey

我正在将 JAX-RS Web 服务部署到 Tomcat servlet 容器.

I am deploying JAX-RS web services to a Tomcat servlet container.

我见过使用以下两种方法之一来指示 web.xml 文件中的资源的代码示例:

I have seen code examples that use either of the following two methods of indicating the resources in the web.xml file:

  <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 发现的.

...where the resources are expected to reside in the com.example package and I suppose are discovered by means of Java RTTI.

<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 类显式标识资源类:

... where the MyApplication class identifies explicitly the resource classes:

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 原型:

Is using the one versus the other method purely a matter of taste and configuration effort and what are some trade-offs to consider? Personally, I prefer the more fine-grained control offered by method 2, however the maven Jersey 2.7 archetype:

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,这让我开始思考.

... is using method 1 and that got me thinking.

推荐答案

方法一(使用servlet的init参数jersey.config.server.provider.packages):是泽西岛特定,仅在包装中查找.它不能在不同的 JAX-RS 实现之间移植.您可以在需要限制考虑的 JAX-RS 资源类/应用程序的场景中使用它.

Method 1 (using servlet's init param jersey.config.server.provider.packages): is Jersey specific and looks only in packages. It is not portable between different JAX-RS implementations. You can use it in scenarios when you want to restrict the considered JAX-RS Resource classes/applications.

方法 2(使用 servlet 的 init 参数 javax.ws.rs.Application):任何 JAX-RS 实现都必须支持此部署选项,因此可移植(尽管如果您切换到另一个 JAX-RS 实现,如 RestEasy,您将不得不更改 servlet 的类).此选项提供了更多粒度(您可以准确选择要考虑的类,而不仅仅是整个包).缺点:你必须写更多的代码.

Method 2 (using servlet's init param javax.ws.rs.Application): any JAX-RS implementation MUST support this deployment option, thus portable (although if you switch to another JAX-RS implementation like RestEasy, you will have to change the servlet's class). This option offers more granularity (you can select exactly the classes to be considered, not only entire packages). The disadvantage: you have to write more code.

方法 3(在 Servlet 版本 3 容器中,您可能已经在其中部署了):仅定义您的 JAX-RS 应用程序而不使用任何 servlet(检查 使用 web.xml 描述符部署) 可能是最好的方式(它也可以在 JAX-RS 实现之间移植,您可以更改 JAX-RS 实现而不更改 web.xml),如果您有明确声明的 JAX-RS 应用程序(您有).

Method 3 (in a Servlet ver. 3 Container, where you probably already deploy): defining only your JAX-RS applications without any servlets (check Deployment using web.xml descriptor) is probably the best way (it is also portable between JAX-RS implementations and you can change the JAX-RS implementation without a change in web.xml), if you have an explicitly declared JAX-RS Application (which you have).

方法 4 如果您想将 war 存档中的所有类部署到 servlet 容器 3(没有明确定义的 JAX-RS 应用程序)中,您也可以以可移植的方式执行此操作.在此处查看:没有 Application 子类的 JAX-RS 应用程序

Method 4 If you want to deploy all classes from your war archive in a servlet container 3 (without an explicitly-defined JAX-RS application), you can do that also in a portable way. Check it here: JAX-RS application without an Application subclass

相关文章