使用GlassFish v4自定义JSON marhsalling

时间:2015-01-20 20:45:57

标签: glassfish jersey jackson jax-rs moxy

我们有一个在Apache TomEE上运行的JAX-RS应用程序。我们稍微定制默认的Jettison提供程序,以更好地遵守JavaScript前端使用的JSON约定。 TomEE允许通过其resources.xml文件执行此操作:

<resources>
    <Service id="jettison" class-name="org.apache.cxf.jaxrs.provider.json.JSONProvider">
        serializeAsArray = true
        dropRootElement = false
        arrayKeys = members,roles
        supportUnwrapped = true
        writeXsiType = false
    </Service>
</resources>

现在我们正在迁移到GlassFish v4.1,我们注意到JSON输出与我们在TomEE中的输出不同 - 因此完全打破了前端。我正在寻找类似的机制来自定义GlassFish中的JSON编组器。事实上,我已经和Jersey,MOXy,Jackson,Jettison有点stuck了。我们如何知道实际使用哪个JSON提供程序?我们如何选择一个?我们如何定制行为?

该应用程序是纯JAX-RS,不直接使用任何JSON处理器,而是依赖于JAXB注释类的编组。引入任何非JavaEE依赖项是非常不受欢迎的,因为该应用程序旨在跨容器移植(TomEE,GlassFish,某天WildFly)。配置文件方法,类似于TomEE,是优选的;程序化方式也是可以接受的 - 但前提是保持可移植性。

1 个答案:

答案 0 :(得分:2)

Glassfish使用MOXy作为默认提供程序。在内部它库来处理Jackson,Jettison和MOXy,但默认是MOXy。有两种方法可以禁用MOXy

  1. 将泽西属性jersey.config.server.disableMoxyJson设置为true
  2. 注册禁用MOXy的其他XxxJsonFeature。例如JacksonFeature
  3. 附带的jersey-media-json-jackson

    请注意,Glassfish附带Jackson提供商,但它是Jackson 1.x.如果你想使用2.x,而不是使用上面列出的jersey-media-json-jackson依赖关系,那么最好使用底层的Jackson提供程序依赖,

    <dependency>
        <groupId>com.fasterxml.jackson.jaxrs</groupId>
        <artifactId>jackson-jaxrs-json-provider</artifactId>
        <version>2.6.0</version>
    </dependency>
    

    您可以为JAXB注释支持注册JacksonJsonProviderJacksonJaxbJsonProvider

    配置Jackson,这是实现ContextResolver的最简单方法,如this answer中所示。 JacksonJsonProvider将查找此ContextResolver以检索用于(反)序列化的ObjectMapper

    如上所述,您还需要记住禁用MOXy。

    还有一点需要注意,此解决方案可移植的。使用JAX-RS,唯一的可移植应用程序配置是通过Application子类

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

    话虽如此,在Glassfish的情况下禁用MOXy只不过是设置一个属性。在Application类中,您可以覆盖返回getProperties()的{​​{1}}。您可以在此处设置属性。因为它只不过是一个字符串(没有外部依赖项),它仍然是可移植的

    Map<String, Object>

    就上述杰克逊的依赖性而言,它也是一种便携式解决方案。它没有任何(JAX-RS)实现具体。它实现并使用标准的JAX-RS API