Grails 2.4命名的JSON配置不起作用

时间:2014-08-29 17:26:53

标签: json spring grails groovy

我无法使用指定的命名配置将对象呈现为JSON。我做错了什么?

我在Bootstrap.groovy init方法中定义了一个命名配置

import com.appromocodes.Project
import com.appromocodes.Promocode
import grails.converters.JSON

class BootStrap {

    def init = { servletContext ->


        JSON.createNamedConfig('apiCheck', {
            JSON.registerObjectMarshaller(Promocode) { Promocode promocode ->
                def map= [:]
                map['code'] = promocode.code
                map['allowedUses'] = promocode.allowedUses
                map['customInfo'] = promocode.customInfo

                return map              
              }
        })

    }
    def destroy = {
    }
}

然后我有一个经典的控制器(不是REST,而是简单的控制器):

import grails.converters.JSON

class ApiV1Controller {

def apiV1Service

    def check() {

        log.info("check");

        def resultMap = apiV1Service.checkPromocode(params.projectKey, params.code)


        if (resultMap.statusCode != ResponseStatus.PROMOCODE_USED) {
        }

        def p = Promocode.get(1)

        JSON.use('apiCheck', {
            render p as JSON
        })

    }

}

我希望调用check动作只会输出apiCheck命名配置中指定的三个属性,而是获取所有bean属性以及metaClass属性“class”和“id”。

如果我没有指定命名配置,那么JSON正确呈现只显示三个属性的bean。

有什么问题?是否可以在非REST控制器中使用namedConfig?

1 个答案:

答案 0 :(得分:7)

DefaultConverterConfiguration因为带有默认配置的JSON作为参数传递给闭包。 That configuration has to be used to registerObjectMarshaller。所以闭包必须如下实现(注意闭包的参数)。

JSON.createNamedConfig('apiCheck', { config ->
     config.registerObjectMarshaller(Promocode) { Promocode promocode ->
         def map= [:]
         map['code'] = promocode.code
         map['allowedUses'] = promocode.allowedUses
         map['customInfo'] = promocode.customInfo

         return map              
     }
})

更简单,更清晰,更实用的实现方式是:

JSON.createNamedConfig( 'apiCheck' ) { 
     it.registerObjectMarshaller( Promocode ) { Promocode promocode ->
         [ 
             code        : promocode.code, 
             allowedUses : promocode.allowedUses,
             customInfo  : promocode.customInfo
         ]
     }
}