Grails 3 JSON 查看自定义呈现一对多关联
Grails 3 JSON Views custom rendering one-to-many associations
好吧,我已经尝试了我所知道的一切来自定义呈现与 JSON 视图的一对多关联,但惨败。
这是我的票务域的一部分(这里一切都很好)...
class TttTicket {
String title
String number
String description
TttUser assignee
String priority
String status
TttUser creator
Date dateCreated
Date lastUpdated
static mappedBy = [subscribers : 'none', creator:'none']
static belongsTo = [project:TttProject, creator:TttUser]
static hasMany = [subscribers: TttUser]
... blar blar
}
这是我关联的 gson 渲染模板...
import ttt_api_server.TttTicket
model {
TttTicket tttTicket
}
json g.render(tttTicket, [excludes:['creator','subscribers','project']]){
creator {
id tttTicket.creator.id
name tttTicket.creator.name
email tttTicket.creator.email
}
project{
id tttTicket.project.id
name tttTicket.project.name
}
}
... 目前运行良好。我现在想限制每个订阅者的属性输出。
如何旋转这些?例如...
import ttt_api_server.TttTicket
model {
TttTicket tttTicket
}
json g.render(tttTicket, [excludes:['creator','subscribers','project']]){
creator {
id tttTicket.creator.id
name tttTicket.creator.name
email tttTicket.creator.email
}
subscibers g.render(){
tttTicket.subscribers.each {sub ->
return {
name sub.name
}
}
}
project{
id tttTicket.project.id
name tttTicket.project.name
}
}
这似乎没有在任何地方记录。我想控制此级别每个订阅者的 JSON 输出。不在域级别,因为我可能需要根据我的 JSON 要求更改 属性 输出。
请帮忙:-(
如果我理解正确,当您对票证进行 REST 调用时,您希望 hasMany 关系内的域对象显示指定的属性(在本例中为订阅者)。但是当您直接调用订阅者时,您需要所有属性。
您可以先创建地图,然后根据创建的地图渲染对象(查看this)。
你的情况:
import ttt_api_server.TttTicket
model {
TttTicket tttTicket
}
json g.render(tttTicket, [excludes:['creator','subscribers','project']]){
creator {
id tttTicket.creator.id
name tttTicket.creator.name
email tttTicket.creator.email
}
def s = tttTicket.subsribers.collect {
[
id: it.id,
name: it.name
]
}
subscribers s //this part is doing the rendering
project{
id tttTicket.project.id
name tttTicket.project.name
}
}
如果这是您希望此对象在呈现为 JSON 时呈现的方式,我建议实施 ObjectMarshaller<JSON>
:
class TttTicketMarshaller implements ObjectMarshaller<JSON> {
@Override
boolean supports(Object object) {
return object instanceof TttTicket
}
@Override
void marshalObject(Object object, JSON converter) throws ConverterException {
TttTicket ticket = (TttTicket)object
def jsonWriter = converter.writer
jsonWriter.object()
jsonWriter.key("title")
jsonWriter.value(ticket.title)
//other fields
jsonWriter.key("creator")
jsonWriter.object()
jsonWriter.key("id")
jsonWriter.value(ticket.creator.id)
//other creator fields
jsonWriter.endObject()
}
}
我不是 100% 确定 object()
和 endObject()
功能,但这似乎是正确的用法。
一旦你有了这个,在你的 BootStrap.groovy
中注册它:
def init = { servletContext ->
JSON.registerObjectMarshaller(new TttTicketMarshaller())
}
有了这一切,您可以简单地使用
render myTicket as JSON
到 return 由编组器定义的 JSON 对象表示
好吧,我已经尝试了我所知道的一切来自定义呈现与 JSON 视图的一对多关联,但惨败。
这是我的票务域的一部分(这里一切都很好)...
class TttTicket {
String title
String number
String description
TttUser assignee
String priority
String status
TttUser creator
Date dateCreated
Date lastUpdated
static mappedBy = [subscribers : 'none', creator:'none']
static belongsTo = [project:TttProject, creator:TttUser]
static hasMany = [subscribers: TttUser]
... blar blar
}
这是我关联的 gson 渲染模板...
import ttt_api_server.TttTicket
model {
TttTicket tttTicket
}
json g.render(tttTicket, [excludes:['creator','subscribers','project']]){
creator {
id tttTicket.creator.id
name tttTicket.creator.name
email tttTicket.creator.email
}
project{
id tttTicket.project.id
name tttTicket.project.name
}
}
... 目前运行良好。我现在想限制每个订阅者的属性输出。
如何旋转这些?例如...
import ttt_api_server.TttTicket
model {
TttTicket tttTicket
}
json g.render(tttTicket, [excludes:['creator','subscribers','project']]){
creator {
id tttTicket.creator.id
name tttTicket.creator.name
email tttTicket.creator.email
}
subscibers g.render(){
tttTicket.subscribers.each {sub ->
return {
name sub.name
}
}
}
project{
id tttTicket.project.id
name tttTicket.project.name
}
}
这似乎没有在任何地方记录。我想控制此级别每个订阅者的 JSON 输出。不在域级别,因为我可能需要根据我的 JSON 要求更改 属性 输出。
请帮忙:-(
如果我理解正确,当您对票证进行 REST 调用时,您希望 hasMany 关系内的域对象显示指定的属性(在本例中为订阅者)。但是当您直接调用订阅者时,您需要所有属性。
您可以先创建地图,然后根据创建的地图渲染对象(查看this)。 你的情况:
import ttt_api_server.TttTicket
model {
TttTicket tttTicket
}
json g.render(tttTicket, [excludes:['creator','subscribers','project']]){
creator {
id tttTicket.creator.id
name tttTicket.creator.name
email tttTicket.creator.email
}
def s = tttTicket.subsribers.collect {
[
id: it.id,
name: it.name
]
}
subscribers s //this part is doing the rendering
project{
id tttTicket.project.id
name tttTicket.project.name
}
}
如果这是您希望此对象在呈现为 JSON 时呈现的方式,我建议实施 ObjectMarshaller<JSON>
:
class TttTicketMarshaller implements ObjectMarshaller<JSON> {
@Override
boolean supports(Object object) {
return object instanceof TttTicket
}
@Override
void marshalObject(Object object, JSON converter) throws ConverterException {
TttTicket ticket = (TttTicket)object
def jsonWriter = converter.writer
jsonWriter.object()
jsonWriter.key("title")
jsonWriter.value(ticket.title)
//other fields
jsonWriter.key("creator")
jsonWriter.object()
jsonWriter.key("id")
jsonWriter.value(ticket.creator.id)
//other creator fields
jsonWriter.endObject()
}
}
我不是 100% 确定 object()
和 endObject()
功能,但这似乎是正确的用法。
一旦你有了这个,在你的 BootStrap.groovy
中注册它:
def init = { servletContext ->
JSON.registerObjectMarshaller(new TttTicketMarshaller())
}
有了这一切,您可以简单地使用
render myTicket as JSON
到 return 由编组器定义的 JSON 对象表示