我在映射中存储了一些GString,并试图在运行时将其评估为:
//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.get(keyFromParams)
获得适当的值 - 替换上面获得的字符串中绑定的占位符
现在的问题是,当我调用placeholderStrings.get(keyFromParams)
时,它会尝试替换字符串中的占位符并抛出异常。
为了解决这个问题,我尝试将占位符字符串值存储为单引号字符串,如:
def placeholderStrings=["nameString":'My name is $name',"professionString":'My profession is $profession']
但现在我没有办法将上面映射中的值转换为GString,以便替换占位符。那么,有人能提出可以做些什么吗?
Lazy GStrings(例如"My name is ${-> name}"
)可能会解决这个问题,但在脚本绑定中注入替换的整个方法对我来说就像是一个黑客(和潜在的安全漏洞)。使用模板引擎可能会更好。Groovy附带了SimpleTemplateEngine
和GStringTemplateEngine
,尽管我被告知使用它们很容易遇到内存泄漏问题(我不知道细节)。
使用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'
编辑
不使用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"