2

マップにいくつかの 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

違いを見るとわかるように、最初のスクリプトではプレースホルダー文字列がバインディングの前に宣言されていましたが、2 番目のスクリプトではバインディングの後に宣言されていました。私のアプリケーションでは、クライアントの要求に基づいて実行時にプレースホルダー文字列を評価する必要があるため、最初の状況と同様のことをしたいと考えています。

  • リクエストが来たら、 を使用して適切な値を取得する必要がありますplaceholderStrings.get(keyFromParams)
  • 上記で取得した文字列のバインディングのプレースホルダーを置き換えます。

問題は、を呼び出すplaceholderStrings.get(keyFromParams)たびに、文字列内のプレースホルダーを置き換えようとし、例外をスローすることです。

問題を解決するために、次のような一重引用符で囲まれた文字列として placeholderString 値を保存しようとしました。

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

しかし、プレースホルダーを置き換えることができるように、上記のマップの値を GString に変換する方法がありません。

4

2 に答える 2

4

Lazy GStrings (例: "My name is ${-> name}") は問題を解決するかもしれませんが、スクリプト バインディングに置換を挿入する全体的なアプローチは、ハック (および潜在的なセキュリティ ホール) のように感じます。テンプレートエンジンを使ったほうがいいかもしれません。SimpleTemplateEngineGroovy にはとが付属しGStringTemplateEngineていますが、メモリ リークの問題が発生しやすいと言われています (詳細はわかりません)。

于 2013-07-13T10:47:58.247 に答える