glassfish - 使用 GlassFish v4 自定义 JSON 编码

标签 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 编码器。其实我已经有点stuck与 Jersey ,MOXy, jackson ,杰蒂森。我们如何知道实际使用的是哪个 JSON 提供程序?我们如何选择一个?我们如何自定义行为?

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

最佳答案

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

  • 设置 Jersey 属性 jersey.config.server.disableMoxyJson true .
  • 注册不同的 XxxJsonFeature禁用 MOXy。例如 JacksonFeature 附带 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>
    

    您可以注册 JacksonJsonProviderJacksonJaxbJsonProvider用于 JAXB 注释支持。

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

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

    还有一点需要注意的是,这个解决方案是可移植的。使用 JAX-RS,唯一的可移植应用程序配置是通过 Application子类
    @ApplicationPath("/api")
    public class MyApplication extends Application {}
    

    话虽如此,在 Glassfish 的情况下禁用 MOXy 无非是设置属性。在 Application类,您可以覆盖 getProperties()返回 Map<String, Object> .您可以在此处设置属性。并且因为它只不过是一个字符串(没有外部依赖项),所以它仍然是可移植的
    @ApplicationPath("/api")
    public class MyApplication extends Application {
        @Override
        public Map<String, Object> getProperties() {
            Map<String, Object> props = new HashMap<>();
            props.put("jersey.config.server.disableMoxyJson", true);
            return props;
        }
    }
    

    就上面的Jackson依赖而言,也是一个可移植的解决方案。它没有特定于 (JAX-RS) 实现。它实现并使用标准的 JAX-RS API

    关于glassfish - 使用 GlassFish v4 自定义 JSON 编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28054821/

    相关文章:

    grails - 部署Grails应用程序时Glassfish服务器问题

    java - 用于多部分表单数据的 Jersey 2 注入(inject)源

    java - Jackson - 使用多态类型列表反序列化对象

    java - jackson 自定义序列化 getter

    rest - 没有为带有 jaxrs 的 rest-service 中的参数找到注入(inject)源

    java - Glassfish:HTTP 500 内部服务器错误无一异常(exception)

    java - 修改 Observable 上的列表

    java - 如何从 Dropwizard 服务发回一条简单的消息?

    json - 模型类中 JsonNode 属性的 springfox swagger 配置

    网 bean 11.2 : No suitable Deployment Server is defined for the project or globally