使用GlassFish v4自定义JSON [英] Customizing JSON marhsalling with GlassFish v4

查看:137
本文介绍了使用GlassFish v4自定义JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 < resources> 
< Service id =jettisonclass-name =org.apache.cxf.jaxrs.provider.json.JSONProvider>
serializeAsArray = true
dropRootElement = false
arrayKeys =成员,角色
supportUnwrapped = true
writeXsiType = false
< / Service>
< /资源>

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



应用程序是纯JAX-RS,不直接使用任何JSON处理器,而是依靠对JAXB注释的类进行编组。任何非JavaEE依赖性的引入都是非常不可取的,因为应用程序旨在跨容器(TomEE,GlassFish,有朝一日WildFly)移植。与TomEE类似,配置文件方法更可取;编程方式也是可以接受的 - 但只有在可移植性得到维护的情况下才行。

解决方案

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


  1. 设置Jersey属性 jersey.config.server.disableMoxyJson

  2. 注册禁用MOXy的另一个 XxxJsonFeature 。例如 JacksonFeature 附带 jersey- media-json-jackson

请注意,Glassfish附带杰克逊提供商,但它是杰克逊1.x.如果你想使用2.x,而不是使用上面列出的 jersey-media-json-jackson 依赖项,最好使用底层的Jackson提供者依赖项,它是

 <依赖关系> 
< groupId> com.fasterxml.jackson.jaxrs< / groupId>
< artifactId> jackson-jaxrs-json-provider< / artifactId>
< version> 2.6.0< / version>
< /依赖关系>

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

配置Jackson是实现 ContextResolver 的最简单方法,如这个答案 JacksonJsonProvider 会查找这个 ContextResolver 来检索使用的 ObjectMapper (de)序列化。

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



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

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

这就是说,对于Glassfish而言,禁用MOXy只不过是设置一个属性。在 Application 类中,可以覆盖返回 Map< String的 getProperties()对象> 。这是您可以设置属性的位置。因为它只不过是一个字符串(没有外部的依赖关系),它仍然是可移植的

  @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);
回报道具;


就上述杰克逊依赖而言,它也是便携式解决方案。它没什么特别的(JAX-RS)实现。它实现并使用标准的JAX-RS API

We've got a JAX-RS application that runs on Apache TomEE. We slightly customize the default Jettison provider to better adhere to JSON conventions used by JavaScript frontend. TomEE allows to do it via its resources.xml file:

<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>

Now we are migrating to GlassFish v4.1, and we notice that JSON output differs from what we had in TomEE - thus completely breaking frontend. I'm looking for similar mechanism to customize JSON marshaller in GlassFish. In fact, I'm already a little bit stuck with Jersey, MOXy, Jackson, Jettison. How do we know which JSON provider is actually used? How do we select one? How do we customize the behavior?

The application is pure JAX-RS and does not use any JSON processor directly, instead relying on marshalling of JAXB-annotated classes. Introduction of any non-JavaEE dependencies is highly undesirable, since the application is intended to be portable across containers (TomEE, GlassFish, some day WildFly). Config-file method, similar to TomEE, is preferable; programmatic way is acceptable, too - but only if portability is maintained.

解决方案

Glassfish uses MOXy as the default provider. Internally it has the libraries to handle Jackson, Jettison, and MOXy, but the default is MOXy. There are two ways to disable MOXy

  1. Set the Jersey property jersey.config.server.disableMoxyJson to true.
  2. Register a different XxxJsonFeature that disables MOXy. For instance the JacksonFeature that comes with jersey-media-json-jackson

Note that Glassfish comes with a Jackson provider, but it is Jackson 1.x. If you want to use 2.x, instead of the using the jersey-media-json-jackson dependency listed above, it would be better to use the underlying Jackson provider dependency, which is

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

You can register the JacksonJsonProvider or the JacksonJaxbJsonProvider for JAXB annotation support.

To configure Jackson, the easiest way to implement a ContextResolver, as seen in this answer. The JacksonJsonProvider will lookup this ContextResolver to retrieve the ObjectMapper used for (de)serialization.

You will also need to remember to disable MOXy, as mentioned above.

Also one thing to note is that this solution is portable. With JAX-RS, the only portable application configuration is through an Application subclass

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

That being said, the disabling of MOXy in the case of Glassfish, is nothing more than setting a property. In the Application class, you can override getProperties() which returns a Map<String, Object>. This is where you can set the property. And because it s nothing more than a String (no outside dependencies), it remains portable

@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;
    }
}

As far as the above Jackson dependency, it is also a portable solution. It it nothing (JAX-RS) implementation specific. It implements and uses standard JAX-RS APIs

这篇关于使用GlassFish v4自定义JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆