首页 文章

将GStrings存储在变量中并在运行时进行评估

提问于
浏览
2

我在 Map 中存储了一些GStrings,并尝试在运行时评估它们:

//this is in begginning of my class or controller or service and is a global variable
def placeholderStrings=["nameString":"My name is $name","professionString":"My profession is $profession"]

//this params map comes after arrival of request from client side and following code is inside the controller
params=["name":"name1","profession":"profession1"]
def paramsKeyMap=params.keySet()
paramsKeyMap.each{
    bindings."$it"=params[it]
    println it
}
println placeholderStrings.get("nameString") // this line gives error as groovy.lang.MissingPropertyException: No such property: name

上面的代码给出了错误,但代码运行如下

params=["name":"name1","profession":"profession1"]
def keyMap=params.keySet()
keyMap.each { 
    binding[it] =params[it] 
    println it // or even binding[it] = 'something' 
}
//Now I am declaring it locally pls note this
def placeholderStrings=["nameString":"My name is $name","professionString":"My profession is $profession"]
println placeholderStrings.get("nameString") // this line gives error as groovy.lang.MissingPropertyException: No such property: name

我们可以看到差异,在第一个脚本中,placeholderStrings在绑定之前声明,而在第二个脚本中,它是在绑定之后 . 我想做类似于第一种情况的事情,因为在我的应用程序中,我需要根据客户端请求在运行时评估占位符字符串 .

  • 当请求到来时,我需要使用 placeholderStrings.get(keyFromParams) 获取适当的值 .

  • 用上面获得的字符串中的绑定替换占位符 .

现在的问题是,当我调用 placeholderStrings.get(keyFromParams) 时,它会尝试替换字符串中的占位符并抛出异常 .

为了解决这个问题,我尝试将placeholderString值存储为单引号字符串,如:

def placeholderStrings=["nameString":'My name is $name',"professionString":'My profession is $profession']

但是现在我无法将上面 Map 中的值转换为GString,以便可以替换占位符 . 任何人都可以建议可以做什么?

2 回答

  • 2

    懒惰的GStrings(例如 "My name is ${-> name}" )可能会解决这个问题,但是在脚本绑定中注入替换的整个方法对我来说就像是一个黑客(和潜在的安全漏洞) . 使用模板引擎可能会更好 . Groovy附带了 SimpleTemplateEngineGStringTemplateEngine ,虽然我很容易遇到内存泄漏问题(我不知道细节) .

  • 4

    使用Expando .

    def exp = new Expando()
    
    exp.nameString = {"My name is $name"}
    exp.professionString = {"My profession is $profession"}
    
    exp.name = "Rahul"
    exp.profession = "SoftwareEngineer"
    
    assert exp.nameString() == 'My name is Rahul'
    assert exp.professionString() == 'My profession is SoftwareEngineer'
    
    exp.name = "Sachin"
    exp.profession = "Cricket"
    
    assert exp.nameString() == 'My name is Sachin'
    assert exp.professionString() == 'My profession is Cricket'
    

    EDIT
    不使用Expando

    def params = [name: 'Rahul', age: 25, profession: 'developer']
    def stringMap = params.collectEntries([:]){k, v ->
        def key = k + "String"
        [(key), "My $k is $v"]
    }
    
    assert stringMap instanceof java.util.LinkedHashMap
    assert stringMap == [nameString:"My name is Rahul", ageString:"My age is 25", professionString:"My profession is developer"]
    assert stringMap.nameString == "My name is Rahul"
    

相关问题