在我的Grails 2.5.0应用程序中,我使用了一堆自定义JSON marshallers来严格控制我的REST端点返回的JSON格式。目前我在这样的服务中注册这些marshallers
class MarshallerRegistrarService {
static transactional = false
LinkGenerator grailsLinkGenerator
// a combination of eager bean initialization and @PostConstruct
// ensures that the marshallers are registered when the app (or
// a test thereof) starts
boolean lazyInit = false
@PostConstruct
void registerMarshallers() {
// a collection of Enums that can be rendered to JSON
def jsonEnums = [PaymentFrequency, Operation]
jsonEnums.each { Class enumType ->
JSON.registerObjectMarshaller(enumType) { Enum enumValue ->
enumValue.toString()
}
}
JSON.registerObjectMarshaller(TimelineItem) { TimelineItem timelineItem ->
def domainInstance = timelineItem.item
return [
date: timelineItem.date,
type: domainInstance.class.simpleName,
item: [id: domainInstance.id],
link: grailsLinkGenerator.link(absolute: true, mapping: 'downloadForm', params: [apiVersion: 'v1', id: domainInstance.id])
]
}
JSON.registerObjectMarshaller(Date) {
TimeZone tz = TimeZone.getTimeZone('UTC')
def formatted = it?.format("yyyy-MM-dd'T'HH:mm:ss'Z'", tz)
return formatted
}
// more marshallers registered here (much more!)
}
}
这种方法的原因之一是我可以在渲染JSON时访问spring bean(例如grailsLinkGenerator
)。
然而,有几个缺点:
registerMarshallers
方法随着编组人数的增加而迅速失控我更喜欢在其自己的类中定义每个编组器并在resources.groovy
中将其注册为Spring bean,这可能吗?
答案 0 :(得分:1)
当然可以这样做:-)
制作所有marshallers @Component
并在实例化期间或之后使用JSON注册它们。另一种方法是使它们@Component
并用接口或基类标记它们并在bootstrap / plugin init中注册它们,如下所示:
ctx.getBeansOfType(MarshallerBase).each { name, bean ->
bean.registerMarshallers()
}
假设每个编组器实现registerMarshallers()
方法。
但是还有更多的方法。