【问题标题】:How do I migrate from Jersey 1.0 to Jersey 2.0?如何从 Jersey 1.0 迁移到 Jersey 2.0?
【发布时间】:2013-06-10 12:05:47
【问题描述】:

我正在尝试升级到 Jersey 2.0,但遇到了很多麻烦,因为 Jersey 的 groupIds 和 artifactIds 已经完全改变,我在 Jersey docs 中找不到迁移计划。

这是我的 pom.xml 以前的样子,编译得很好:

        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-server</artifactId>
            <version>1.17</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-servlet</artifactId>
            <version>1.17</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-server-linking</artifactId>
            <version>1.17.1</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-client</artifactId>
            <version>1.17.1</version>
        </dependency>

这些应该改成什么? This unrelated StackOverflow question was somewhat helpful, 但我很难找到 @Ref 注释移动到的位置。


更新

  1. 似乎@Ref 不再存在,或者至少it's not mentioned in the documentation anymore 不存在。现在你使用UriBuilder
  2. I found a very helpful section in the documentation that answers my maven issues
  3. HTTPBasicAuthFilter 已重命名为 HttpBasicAuthFilter。注意大写。
  4. Client client = Client.create(); 变成了Client client = ClientBuilder.newClient();
  5. 这个:

        String json = client
            .resource(getBaseUrl() + url)
            .accept(MediaType.APPLICATION_JSON_TYPE)
            .get(String.class);
    

    变成了

    String json = client
            .target(getBaseUrl())
            .path(url)
            .request(MediaType.APPLICATION_JSON_TYPE)
            .get(String.class);
    

【问题讨论】:

  • @PaulBellora 不,还没有解决。这只是我掌握的信息。还有更多问题。
  • 4年后你的问题解决了吗?

标签: maven jersey glassfish-2.x jersey-1.0 jersey-2.0


【解决方案1】:

你没有。

Jersey 2.0 缺少 Jersey 1.0 的许多功能。与提交者告诉你的相反,有些事情现在完全不可能实现(例如 Guice、Spring 集成)。事情似乎在表面上起作用,但一旦你深入挖掘,你会发现很多功能仍然被破坏。

很多 1.x 插件在 2.x 中不存在,主要是因为前面提到的损坏。

鉴于此,我建议在可预见的未来暂缓使用 Jersey 2.x。希望提交者能在来年清理这个问题。

【讨论】:

  • Spring 集成部分不再适用:jersey.java.net/documentation/latest/spring.html
  • 我们使用 hk2.java.net/spring-bridge 来集成 Spring 4 和 Jersey 2
  • @Gili 你还有这种感觉吗?自从您提出此建议以来已经有几年了,我想知道您在 Jersey 1.x -> 2.x 迁移中仍然发现什么问题。
  • @Andrew 我相信大部分缺失的功能最终都添加到了 2.x 中,但是迁移现有代码仍然非常痛苦。此外,Guice 和 Spring 的集成仍然存在根本性的问题(鉴于当前的设计,无法正确实现)。我对 2.x 最大的不满是它背后的团队忽略了用户反馈(然后攻击那些叫他们的用户)。我使用并为 Jersey 1.x 贡献插件的主要原因是强大的开发人员/社区支持。当甲骨文收购 Sun 时,他们更换了团队,一切都走下坡路。
【解决方案2】:

我不得不说这是颈部疼痛。 我们目前正在深入迁移相对较大的 3 年以上的客户端-服务器项目,我真的想咬掉我的脖子。 希望我们在斗争的尽头...... 虽然确实有迁移指南,但无论如何它并不全面。

  • UniformInterfaceException(和其他)已不复存在。

取而代之的是,它被 WebApplication 异常和后继者所取代。迁移指南中没有提及这一点,这非常重要。

  • JSON 支持

迁移指南说:

JSON 支持在 Jersey 2.x 中发生了某些变化。最多 开发人员的明显区别在于初始化和 配置。

在 Jersey 1.x 中,JAXB/JSON 支持被实现为一组 jersey-json 模块中的 MessageBodyReaders 和 MessageWriters。 在内部,有几种 JSON to Object 的实现 映射范围从泽西岛自己的定制解决方案到第三方 提供商,例如 Jackson 或 Jettison。 JSON的配置 支持集中在 JSONConfiguration 和 JSONJAXBContext 类。

太好了。如果您选择了“泽西岛自己的定制解决方案”(无论出于何种原因,我们都这样做了)怎么办?在球衣 2 中没有其他选择。我尝试使用 Jettison、Jackson 和 Moxy 提供程序生成相同的 JSON 格式。我没有成功。作为参考,我在这里未回答的问题:Jersey 2 JSON Jettison unwrapping root element

【讨论】:

    【解决方案3】:

    请参阅 Jersey 文档中的 1.x to 2.0 migration guide。 (2019链接1.x to 2.0 migration guide

    【讨论】:

    • 这很有帮助,但我不会说完全全面。 EG:没有提到@Ref 以及它的去向。没有提到迁移 maven pom 等。
    【解决方案4】:

    看起来@InjectLink@Ref 的替代品。

    从那个链接,我可以把它放到我的 pom.xml 中:

        <dependency>
            <groupId>org.glassfish.jersey.ext</groupId>
            <artifactId>jersey-declarative-linking</artifactId>
            <version>2.6</version>
        </dependency>
    

    然后我使用了现有的 @Ref 并能够替换为 @InjectLink

    public Long id; // This id is referenced below in the link
    
    @InjectLink(resource = FavoriteResource.class, method = "updateFavorites", bindings = {
            @Binding(name = "listId", value = "${instance.id}")
    })
    public URI linkURI;
    

    看起来 @Ref 中的一些 JavaDocs 甚至在 @InjectLink 中,这将进一步确认它是替代品:

    /**
     * ...
     * @Ref(resource=SomeResource.class)
     * @Ref(resource=SomeResource.class, bindings={
     *   @Binding(name="id" value="${instance.id}"}
     * )
    */
    

    编辑:

    棘手的东西。我还需要一件来为我完成这项工作。在web.xml, 我现在有:

    <servlet>
        <servlet-name>jersey-servlet</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.mycompany.root</param-value>
        </init-param>
        <init-param>
            <param-name>jersey.config.server.provider.classnames</param-name>
            <param-value>com.mycompany.root.web.filter.AuditResourceFilterFactory;com.mycompany.root.web.filter.OtherAuditResourceFilterFactory</param-value>
        </init-param>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.mycompany.root.web.resource.config.CustomResourceConfig</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    

    最后,CustomResourceConfig.java 看起来像这样

    import org.glassfish.jersey.linking.DeclarativeLinkingFeature;
    import org.glassfish.jersey.server.ResourceConfig;
    
    public class CustomResourceConfig extends ResourceConfig {
        public CustomResourceConfig() {
            packages("org.glassfish.jersey.examples.linking");
            register(DeclarativeLinkingFeature.class);
        }
    }
    

    【讨论】:

      【解决方案5】:

      您可以按照以下步骤从 Jersey 1 迁移到 Jersey 2:

      在 POM 文件中添加以下依赖项: Jersey 2.23.2 依赖项

         <dependency>
          <groupId>org.glassfish.jersey.containers</groupId>
          <artifactId>jersey-container-servlet-core</artifactId>
          <version>2.23.2</version>
         </dependency>
         <dependency>
          <groupId>org.glassfish.jersey.ext</groupId>
          <artifactId>jersey-spring3</artifactId>
          <version>2.23.2</version>
          <exclusions>
           <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
           </exclusion>
           <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
           </exclusion>
           <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
           </exclusion>
          </exclusions>
         </dependency>
         <dependency>
          <groupId>org.glassfish.jersey.core</groupId>
          <artifactId>jersey-client</artifactId>
          <version>2.23.2</version>
         </dependency>
         <dependency>
          <groupId>org.glassfish.jersey.media</groupId>
          <artifactId>jersey-media-moxy</artifactId>
          <version>2.23.2</version>
         </dependency>
         <dependency>
          <groupId>org.glassfish.jersey.ext</groupId>
          <artifactId>jersey-entity-filtering</artifactId>
          <version>2.23.2</version>
         </dependency>
         <dependency>
          <groupId>org.glassfish.jersey.core</groupId>
          <artifactId>jersey-server</artifactId>
          <version>2.23.2</version>
         </dependency>
         <dependency>
          <groupId>org.glassfish.jersey.core</groupId>
          <artifactId>jersey-common</artifactId>
          <version>2.23.2</version>
         </dependency>
         <dependency>
          <groupId>org.glassfish.jersey.bundles.repackaged</groupId>
          <artifactId>jersey-guava</artifactId>
          <version>2.23.2</version>
         </dependency>
         <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-jackson</artifactId>
            <version>2.23.2</version>
            <exclusions>
             <exclusion>
              <groupId>com.fasterxml.jackson.core</groupId>
               <artifactId>jackson-annotations</artifactId>
             </exclusion>
            </exclusions>
         </dependency>
         <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.5.4</version>
         </dependency>
         <dependency>
             <groupId>org.glassfish.jersey.media</groupId>
             <artifactId>jersey-media-multipart</artifactId>
             <version>2.23.2</version>
         </dependency>
      
         <dependency>
             <groupId>org.jvnet</groupId>
             <artifactId>mimepull</artifactId>
             <version>1.6</version>
         </dependency>
      

      在 Web.xml 中创建以下条目:

      <?xml version="1.0" encoding="UTF-8"?>
      <web-app id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
      
       <servlet>
        <servlet-name>jersey-servlet</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
         <param-name>javax.ws.rs.Application</param-name>
         <param-value>com.jsg.resource.initializer.RestResourceInitializer</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
       </servlet>
       <servlet-mapping>
        <servlet-name>jersey-servlet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
       </servlet-mapping> '
      
             <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
       </listener>
       <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
       </context-param>
            <resource-ref>
              <description>DB Connection</description>
              <res-ref-name>jdbc/myAppName</res-ref-name>
             <res-type>javax.sql.DataSource</res-type>
             <res-auth>Container</res-auth>
         </resource-ref>
      </web-app>
      

      在 RestResourceIntializer 中编写如下代码

          package com.jsg.resource.initializer;
      
          import java.util.HashSet;
          import java.util.Set;
          import javax.ws.rs.core.Application;
      
          public class RestResourceInitializer extends Application {
      
           /**
            * Gets the classes.
            *
            * @return the classes
            */
           public Set<Class<?>> getClasses() {
            Set<Class<?>> classes = new HashSet<Class<?>>(); 
      
            // Resources
            classes.add(org.glassfish.jersey.jackson.JacksonFeature.class);
            classes.add(org.glassfish.jersey.server.spring.scope.RequestContextFilter.class);
            classes.add(org.glassfish.jersey.media.multipart.MultiPartFeature.class);
      
                         //Rest classes within Application.
                          classes.add(com.jsg.rest.AbcRestService.class);
      
            classes.add(com.jsg.rest.CdeRestService.class);
            return classes;
           }
          }
      

      现在,如果您将在 websphere 上部署具有上述更改的代码,您将收到以下异常:

      Caused by: java.lang.NoSuchMethodError: javax/ws/rs/core/Application.getProperties()Ljava/util/Map; at org.glassfish.jersey.server.ApplicationHandler.(ApplicationHandler.java:287) at org.glassfish.jersey.servlet.WebComponent.(WebComponent.java:311)
      

      上述异常的原因是,Websphere 支持 JAX-RS 1 实现,但是我们正在部署 Jersey 2 代码,即 Jax-rs 2 实现。

      解决上述异常的步骤:

      所以基本上我们要做的就是强制 WebSphere 选择我们的 Jersey 2 jar,而不是默认的 Jax-rs 1。我们需要按照以下步骤进行操作

      1) 通过将以下 JVM 属性设置为 true 来禁用内置的 JAX-RS

      com.ibm.websphere.jaxrs.server.DisableIBMJAXRSEngine=true
      

      可以通过 WebSphere 的管理控制台设置此属性,方法是转到 Servers->All Server -> ->Server Infrastructure -> Java and Process Management ->Process Deifinition ->Additional Properties-> Java Virtual Machine ->Additional Properties -> 自定义属性

      2) 创建具有 Jersey 2 罐和 Spring 4 罐的独立共享库 可以通过 Websphere 的管理控制台通过转到 Environment-> Shared Libraries ->New

      来创建独立的共享库

      在类路径框中,我们需要输入服务器上文件夹的路径,我们已经放置了所有 Jersey 2 和 Spring 4 的罐子

      /var/was/server2/jerseyLib1/spring-context-4.3.4.RELEASE.jar
      /var/was/server2/jerseyLib1/spring-core-4.3.4.RELEASE.jar
      /var/was/server2/jerseyLib1/spring-beans-4.3.4.RELEASE.jar
      /var/was/server2/jerseyLib1/spring-aop-4.3.4.RELEASE.jar
      /var/was/server2/jerseyLib1/spring-web-4.3.4.RELEASE.jar
      /var/was/server2/jerseyLib1/spring-expression-4.3.4.RELEASE.jar
      /var/was/server2/jerseyLib1/spring-bridge-2.5.0-b05.jar
      /var/was/server2/jerseyLib1/hk2-locator-2.5.0-b05.jar
      /var/was/server2/jerseyLib1/hk2-api-2.5.0-b05.jar
      /var/was/server2/jerseyLib1/hk2-utils-2.5.0-b05.jar
      /var/was/server2/jerseyLib/javax.inject-2.5.0-b05.jar
      /var/was/server2/jerseyLib1/javax.annotation-api-1.2-b03.jar
      /var/was/server2/jerseyLib1/javax.ws.rs-api-2.0.1.jar
      /var/was/server2/jerseyLib1/jersey-client-2.23.2.jar
      /var/was/server2/jerseyLib1/jersey-spring3-2.23.2.jar
      /var/was/server2/jerseyLib1/jersey-container-servlet-core-2.23.2.jar
      /var/was/server2/jerseyLib1/jersey-server-2.23.2.jar
      /var/was/server2/jerseyLib1/jersey-common-2.23.2.jar
      
      /var/was/server2/jerseyLib1/jersey-guava-2.23.2.jar
      

      同样在类加载部分,选择“为此共享库使用隔离类加载器”

      然后最后点击 Apply 和 Ok,我们就完成了隔离共享库的创建。

      1. 在管理控制台中将这个隔离的共享库与您的应用程序war文件绑定,如下所示

        a) 应用程序 -> 所有应用程序 -> 点击您的应用程序名称 b) 转到 References -> Shared Library References -> Reference Shared Libraries -> 选择您的应用程序战争(不是耳朵),然后单击确定。 c) 在左侧的“Available”组合框中选择我们在第 2 步中创建的库,并将其放在“Selected”组合框中的右侧,然后单击确定。 这样,我们将隔离的共享库与应用程序 war 文件相关联。

      2. 重新启动服务器,应用程序应该已启动并运行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-06
        • 1970-01-01
        • 2014-01-14
        • 1970-01-01
        • 2017-02-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多