通过Grail的bean DSL配置Jackson的ObjectMapper

时间:2013-07-17 09:03:38

标签: spring grails jackson

我需要在grails中使用com.fasterxml.jackson.databind.ObjectMapper的共享实例,所以我认为最标准的方法是通过bean DSL。 我在resources.groovy

中尝试了类似的东西(有许多变体,比如使用委托关键字)
objectMapper(ObjectMapper) { bean ->
    bean.setVisibility(PropertyAccessor.ALL, Visibility.ANY)
    bean.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
}

但它不起作用,ObjectMapper配置为默认方式,这对grails不起作用。 我使用了一种解决方法,它可以满足我的需求(在BootStrap.groovy中):

def init = { servletContext ->
    def bean = Holders.applicationContext.objectMapper
    bean.setVisibility(PropertyAccessor.ALL, Visibility.ANY)
    bean.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
}

有人能指出我如何在豆类DSL中进行操作(恕我直言)吗?

3 个答案:

答案 0 :(得分:1)

bean 闭包参数的类型属于AbstractBeanDefinition的某个子类型,它不引用实际的对象实例本身。

有多种方法可以设置可见性并配置ObjectMapper实例:

您可以在Grails中使用所有Spring IoC容器机制进行bean实例化。

不是说我有那个确切的用例,但我倾向于创建一个自定义工厂bean并在那里放置ObjectMapper配置的逻辑。

答案 1 :(得分:1)

在构造函数中提供JsonFactory,而不是使用默认构造函数。

//resources.groovy
beans = {
    jf(com.fasterxml.jackson.core.JsonFactory)

    objectMapper(ObjectMapper, jf){
        visibility(PropertyAccessor.ALL, Visibility.ANY)
        configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
    }
}

这可以在控制台中验证为:

assert grailsApplication.mainContext.objectMapper instanceof com.fasterxml.jackson.databind.ObjectMapper

答案 2 :(得分:1)

对于可见性位,您可以设置VisibilityChecker而不是使用方便setVisibility方法

vc(VisibilityChecker.Std, Visibility.ANY)

objectMapper(ObjectMapper) {
  visibilityChecker = ref('vc')
}

但是configure调用更加困难,你必须使用工厂bean方法来调用方法,定义一个单独的bean。关键是你不想自己调用这些方法,而是试图告诉Spring当它想要创建bean时需要调用

objectMapperConfig(objectMapper:'configure',
                     DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)

由于configure返回对映射器本身的引用,因此确保以正确的顺序解析依赖关系的更好方法可能是

vc(VisibilityChecker.Std, Visibility.ANY)

objectMapperUnconfigured(ObjectMapper) {
  visibilityChecker = ref('vc')
}

objectMapper(objectMapperUnconfigured:'configure',
                     DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)

然后使用objectMapper作为您注入其他地方的bean。