如何使用 Grails 4 JSON 视图呈现域对象的映射

2024-03-13

这是以下问题:如何将映射呈现为 Grails 4 JSON 视图中的属性 https://stackoverflow.com/q/69322504/715608

我有以下 JSON 视图,我想渲染以下值mealsByPerson地图使用_breakfast.gson模板。另外,我希望能够通过allCaps模型属性来自_foo.gson to breakfast.gson

/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
}

Foo控制器

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"
        }
    }
}

示例项目

https://github.com/tonyerskine/rendermapexample https://github.com/tonyerskine/rendermapexample


UPDATE: 请检查我的改进的答案 https://stackoverflow.com/a/69421019/6419922.

这是我(有点)老式的方法:

First,由于 allCaps 要求可能不仅对于特定的控制器/操作有用,我会添加一个asMap方法到Breakfast域类本身。它将所有字符串属性大写,如果它的参数allCaps为 true,并返回Map具有所有对象的属性:

class Breakfast {

    String meat
    String eggs
    String side
    Integer number // Just another random propperty 

    static constraints = {
    }

    // Generic version, We asume we need allCaps for all String properties  
    def asMap(boolean allCaps=false) {
        def breakfast = [:]
        this.properties.each { key, value ->
            if (value && value.class == String && allCaps == true) {
                breakfast[key] = value.toUpperCase() 
            } else {
                breakfast[key] = value
            } 
        }
        return breakfast
    }

    // An alternate/sillier version 
    def asMapSimpler(boolean allCaps=false) {
        return [
            meat:meat.toUpperCase(),
            eggs:eggs.toUpperCase(),
            side:side.toUpperCase(),
            number: number
        ]
    }

}

Next,我们可以使用asMap中的方法FooController:

class FooController {
    static responseFormats = ['json', 'xml']
    
    def index() {

        // default: false 
        def allCaps = params.boolean("allCaps") ?: false

        Map<String, Map> mealsByPerson = [
            Tom: new Breakfast(meat: "bacon", eggs: "scrambled", side: "hashbrowns").asMap(allCaps),
            Jack: new Breakfast(meat: "sausage", eggs: "over easy", side: "pancakes").asMap(allCaps)
        ]

        render template: "foo", model: [
            cost: 12.34f,
            date: new Date(),
            mealsByPerson: mealsByPerson,
            allCaps: allCaps
        ]
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Grails 4 JSON 视图呈现域对象的映射 的相关文章

随机推荐