对于杰克逊,如何安全地共享一个ObjectMapper?有没有不可变的ObjectMapper?

问题描述:

映射器实例完全是线程安全的,不需要为单次使用创建映射器,但可以更改映射器的配置。对于杰克逊,如何安全地共享一个ObjectMapper?有没有不可变的ObjectMapper?

尽管ObjectMapper具有copy函数来复制基于存在映射器的自定义配置,但如果我共享映射器,并不能保证当有人想要自定义映射器时,它们将复制共享映射器。所以我想要一个不可变的映射器来共享,如果有人不小心改变了共享映射器,应该抛出一些异常。

有没有这样的事情?

+0

我将创建ObjectMapper公正公开一些必要的功能 – Jerry06

+0

的包装,相反,我只是想隐藏一些功能为了防止配置发生变化,这似乎是非常常见的用例,是否存在这种包装?如果不是,我会为自己创建一个。 – wener

+0

一个选项可能是共享一个ObjectWriter实例,而不是ObjectMapper。尽管我相信这不是它的预期目的,但这个类似乍一看是不变的。 – Henrik

写不可变的包装比我想象的有CGLIB

/** 
* Create a immutable mapper, will hide some config change operation 
*/ 
@SuppressWarnings("unchecked") 
static <T extends ObjectMapper> T immutable(T mapper) { 
    Enhancer enhancer = new Enhancer(); 
    enhancer.setSuperclass(ObjectMapper.class); 
    enhancer.setCallback((InvocationHandler) (proxy, method, args) -> { 
     if (Modifier.isPublic(method.getModifiers())) { 
      // banned operation 
      String name = method.getName(); 
      boolean match = name.startsWith("set") || 
       name.startsWith("add") || 
       name.startsWith("clear") || 
       name.startsWith("disable") || 
       name.startsWith("enable") || 
       name.startsWith("register") || 
       name.startsWith("config"); 

      if (match) { 
       throw new UnsupportedOperationException(
        "Can not modify the immutable mapper, copy the mapper first"); 
      } 
     } 
     if (!method.isAccessible()) { 
      method.setAccessible(true); 
     } 
     return method.invoke(mapper, args); 
    }); 
    return (T) enhancer.create(); 
} 

由于配置得到映射是不可改变的容易,所以我不需要隐藏吸气。

一种方法是不共享ObjectMapper实例,而是正确地配置它,然后共享由ObjectMapper创建的ObjectWriterObjectReader实例。

ObjectMapper om = new ObjectMapper(); 
// Configure to your needs 
om.enable(...); 
om.disable(...); 

// Distribute these to the parts of the program where you fear configuration changes. 
ObjectWriter writer = om.writer(); 
ObjectReader reader = om.reader(); 

这也似乎是由杰克逊的开发商青睐的办法:https://*.com/a/3909846/13075