【问题标题】:Use Jackson as JAXB-JSON-processor in JavaEE Application在 JavaEE 应用程序中使用 Jackson 作为 JAXB-JSON 处理器
【发布时间】:2015-06-24 06:06:33
【问题描述】:

我看过很多关于这个的文章和 SO-questions - 但我就是不明白。 我的目标是在 JavaEE 应用程序中使用 Jackson 作为 JSON 处理器。到目前为止我有什么?

pom.xml

  • 这一个

    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>2.17</version>
    </dependency>
    
  • 还是这个(到底哪个是正确的?)

    <dependency>
        <groupId>com.fasterxml.jackson.jaxrs</groupId>
        <artifactId>jackson-jaxrs-json-provider</artifactId>
        <version>2.5.2</version>
    </dependency>
    
  • 加上这个(由于this article,因为自动发现将不再存在于杰克逊包中):

    <dependency>
        <groupId>org.glassfish.jersey.ext</groupId>
        <artifactId>jersey-metainf-services</artifactId>
        <version>2.17</version>
    </dependency>
    

web.xml

简单的 REST 注册:

<servlet>
    <servlet-name>javax.ws.rs.core.Application</servlet-name>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>javax.ws.rs.core.Application</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

一个简单的对象

import com.fasterxml.jackson.annotation.JsonProperty;

public class Dummy {
    private String name;

    @JsonProperty("username")
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

REST 资源

@GET
@Path("test")
@Produces(MediaType.APPLICATION_JSON)
public Response getRequest() {
    Dummy dummy = new Dummy();
    dummy.setName("rolf");

    return Response.ok(dummy).build();
}

输出是

{"name":"rolf"}

而不是预期的

{"username":"rolf"}

更新

我正在使用 GlassFish 应用服务器。

【问题讨论】:

标签: java jaxb jersey jackson jax-rs


【解决方案1】:

我的猜测是您使用的是 Glassfish,它使用 MOXy 作为其默认 JSON 提供程序。您可以使用 &lt;init-param&gt; 禁用它。

<init-param>
    <param-name>jersey.config.server.disableMoxyJson</param-name>
    <param-value>true</param-value>
</init-param>

jersey-media-json-jackson 具有自动发现功能,应该会自动注册它。我不确定 Glassfish 的自动发现功能,以及它内部使用的可能较低版本的 Jersey,以及它是否会导致它不被注册。但无论哪种方式,您配置 web.xml 的方式是启用类路径扫描,因此无论如何都应该选择 Jackson 提供程序。

一些仅供参考

  • jersey-media-json-jackson 实际上使用了jackson-jaxrs-json-provider。它只是将其包装在 JacksonFeature 中,并启用自动发现它。
  • 如果还是不行,可以尝试创建一个功能来处理注册和禁用。例如

    @Provider
    public class JsonFeature implements Feature {
        @Override
        public boolean configure(FeatureContext context) {
            context.property("jersey.config.server.disableMoxyJson", true);
            // this is in jersey-media-json-jackson
            context.register(JacksonFeature.class);
    
            // or from jackson-jaxrs-json-provider
            context.register(JacksonJsonProvider.class);
            // for JAXB annotation support
            context.register(JacksonJaxbJsonProvider.class);
    
            return true;
        }
    }
    

【讨论】:

  • 你是对的,它是 GlassFish。我希望所有这些都可以独立于应用程序服务器来处理,因此也可以独立于目标 JAXB 实现。
  • 使用字符串属性。这将不依赖于实现。使用另一种实现,该属性将被简单地忽略。如果您不想使用 jersey-media-json-jackson,因为那是特定于 Jersey 的,那么如果由于某种原因没有从类路径扫描中提取来自 jackson-jaxrs-json-provider 的 Jackson 提供程序,您可以在上面的 Feature 中注册它。 register(JacksonJsonJaxbProvider.class)。您可以查看 jar,还有其他类,例如 ExceptionMapper,您可能还想注册。但这应该由类路径扫描来获取
  • 而且我不知道您所说的 JAXB 实现是什么意思。这个问题与JAXB无关
  • 好吧,那是误导。我绝对需要命名 Jackson 库(我认为 Jersey 将其用作对象反序列化的 JAXB 实现,不是吗?),但我不喜欢命名 Jersey 库,因为它只是在 GlassFish 中使用。我最喜欢的目标是拥有一个也适用于其他应用程序服务器的解决方案。
  • 奇怪的结论:现在它可以与我的问题中的设置一起使用,除了删除 jackson-jaxrs-json-provider 依赖项。无论如何,谢谢您的回复,这仍然很有帮助!在此基础上,我有another question,它将最终解决我的整个问题。
猜你喜欢
  • 2011-10-13
  • 1970-01-01
  • 2014-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-03
  • 2011-03-17
  • 1970-01-01
相关资源
最近更新 更多