这是一个后续问题:How to Render a Map as a property in a Grails 4 JSON View
我有下面的JSON视图,我想使用_breakfast.gson
模板呈现mealsByPerson
map的值。
/foo/_foo.gson
import rendermapexample.Breakfast
model {
Float cost
Date date
Map<String, Breakfast> mealsByPerson
Boolean allCaps
}
json {
date date
cost cost
mealsByPerson g.render(mealsByPerson){} //HOW DO I PASS `allCaps` to this template?
// This doesn't work
// mealsByPerson g.render(mealsByPerson, model: [allCaps: true]){}
}
/breaskfast/_breaskfast.gson
import rendermapexample.Breakfast
model {
Breakfast breakfast
Boolean allCaps
}
json {
meat allCaps ? breakfast.meat.toUpperCase() : breakfast.meat
eggs allCaps ? breakfast.eggs.toUpperCase() : breakfast.eggs
side allCaps ? breakfast.side.toUpperCase() : breakfast.side
}
脚踏控制器
package rendermapexample
class FooController {
static responseFormats = ['json', 'xml']
def index() {
Map<String, Breakfast> mealsByPerson = [
Tom: new Breakfast(meat: "bacon", eggs: "scrambled", side: "hashbrowns"),
Jack: new Breakfast(meat: "sausage", eggs: "over easy", side: "pancakes")
]
render template: "foo", model: [
cost: 12.34f,
date: new Date(),
mealsByPerson: mealsByPerson,
allCaps: params.boolean("allCaps")
]
}
}
所需输出
http://localhost:8080/foo
{
"cost": 12.34,
"date": "2021-09-25T01:11:39Z",
"mealsByPerson": {
"Tom": {
"eggs": "scrambled",
"meat": "bacon",
"side": "hashbrowns"
},
"Jack": {
"eggs": "over easy",
"meat": "sausage",
"side": "pancakes"
}
}
}
http://localhost:8080/foo?allCaps=true
{
"cost": 12.34,
"date": "2021-09-25T01:11:39Z",
"mealsByPerson": {
"Tom": {
"eggs": "SCRAMBLED",
"meat": "BACON",
"side": "HASHBROWNS"
},
"Jack": {
"eggs": "OVER EASY",
"meat": "SAUSAGE",
"side": "PANCAKES"
}
}
}
3条答案
按热度按时间ds97pgxw1#
更新:请检阅我的**improved answer**。
这是我的(一种)老派方法:
首先,由于allCaps要求可能不仅对特定的控制器/操作有用,我将向
Breakfast
域类本身添加一个asMap
方法。如果参数allCaps
为true,则它将所有String属性大写,并返回一个包含所有对象属性的Map
:接下来,我们可以在
FooController
中使用asMap
方法:tjrkku2a2#
终于成功了
x1月0n1x日
_mealsByPerson2.gson
注意:这 * 不 * 适用于
_mealByPerson.gson
必须使用标准循环,而不是
each
闭包,才能使其正常工作txu3uszq3#
重新审视问题
我重新审视了这个问题和我之前的答案,并决定发布这个答案,而不是编辑前者,在这里解决了收到的一些意见/建议,以改进我提出的解决方案。
我将表示逻辑从域类中移走。为了实现这一点,我探索了三种不同的方法:
1.使用Grails服务
1.仅使用模板
为了清楚起见,我在
URLMappings.groovy
中添加了以下Map:方法1:使用Grails服务
请注意,在
FooController
中,服务beanfooService
作为参数包含在对JSON视图的respond
调用中。FooService.太棒了
FooController.常规
引道1.gson
当然,我们可以将
toAllCaps
代码放入POJO静态实用程序类中,然后将其导入approach2.gson
,而不是将fooService
bean作为参数传递。方法2:JSON视图端的编码
如果在JSON视图端需要更多的控制,我们可以将
toAllCaps
函数从FooService.groovy
移到approach1.gson
,并丢弃FooService.groovy
。FooController.常规
方法2.gson
方法3:仅使用模板
在这里,我打算减少传统的groovy编码,而更多地依赖于JSON视图模板,正如官方文档中所概述的那样。
请注意以下注意事项:
1.我使用
mealsByPerson
的ArrayList
变体,因为JSON视图模板的某些功能需要一个实现Iterator
接口的对象。**重要提示:**这将生成一个由单独的对象组成的JSON Array,而不是像原始问题中所述的那样,生成一个包含所有Map条目的JSON对象。1.我不得不禁用JSON视图的静态编译。这是因为
mealsByPerson
中的一些JSON对象名是动态的(即它们不仅仅是标签,而是实际数据)。即来自原始帖子的“Tom”和“Jack”对象名。应用程序.yml
FooController.常规
方法3.gson
_按人员用餐.gson
_早餐.gson