我的代码在 groovy 中使用评估是否有任何错误?
Is any error in my code in using evaluate in groovy?
我将值设置为嵌套映射,键都存在,这是我的代码:
def map = [a1:[a2:[a3:'a123']], b1:[b2:[b3_1:'b234', b3_2:'b345']], d1:'d1']
def name2 = "b1:::b2:::b3_1"
def data = "test"
def separator = ":::"
def names = name2.split(separator)
setValue(map, names, data)
def setValue(def map, def keys, def data) {
tmpMap = map
String str = 'map'
for (i = 0; i < keys.size(); i++) {
str = str.concat('.'+ keys[i])
}
str = str.concat(" = '" + data + "'")
evaluate(str)
}
str 内容将是 "map.b1.b2.b3_1 = 'test'"
我可以手动运行它并且地图内容被更改,但是当我使用评估时,出现"java.lang.NullPointerException: Cannot get property 'b2' on null object"的错误,请你告诉我代码有什么问题,非常感谢。
你想做的事很难...
一种方法是使用 Eval.x
,并将地图作为 x
:
传递
def setValue(Map map, String[] keys, String data) {
def command = "x.${keys.join('.')} = '$data'"
Eval.x(map, command)
}
所以在这里,命令是:x.b1.b2.b3_1 = 'test'
我们用 x
作为 map
的值来评估它
另一种(比较难看)的方法是使用inject遍历map直到最后一个key,然后设置这个返回对象的最后一个key的值:
def setValue(Map map, String[] keys, String data) {
keys[0..-2].inject(map) { a, b -> a."$b" }."${keys[-1]}" = data
}
尽管如此,您还是应该小心评估代码....
例如,您可能会收到以下输入:
def name2 = "val = { -> println \"${System.properties.'user.name'}\" }.call(); def a"
计算表达式(对我而言):
x.val = { -> println "tim" }.call(); def a = 'test'
然后打印用户名...您可以看到如何调整它以从 Internet 下载文件并将其放在某人的计算机上...
如果可以...您应该避免这种情况...或者至少有严格的允许内容白名单
递归方法:
def setValue(def map, List keys, def data) {
return keys.size()>1 ?
setValue(map[keys[0]],keys.subList(1,keys.size()),data) :
map.put(keys[0],data)
}
我将值设置为嵌套映射,键都存在,这是我的代码:
def map = [a1:[a2:[a3:'a123']], b1:[b2:[b3_1:'b234', b3_2:'b345']], d1:'d1']
def name2 = "b1:::b2:::b3_1"
def data = "test"
def separator = ":::"
def names = name2.split(separator)
setValue(map, names, data)
def setValue(def map, def keys, def data) {
tmpMap = map
String str = 'map'
for (i = 0; i < keys.size(); i++) {
str = str.concat('.'+ keys[i])
}
str = str.concat(" = '" + data + "'")
evaluate(str)
}
str 内容将是 "map.b1.b2.b3_1 = 'test'" 我可以手动运行它并且地图内容被更改,但是当我使用评估时,出现"java.lang.NullPointerException: Cannot get property 'b2' on null object"的错误,请你告诉我代码有什么问题,非常感谢。
你想做的事很难...
一种方法是使用 Eval.x
,并将地图作为 x
:
def setValue(Map map, String[] keys, String data) {
def command = "x.${keys.join('.')} = '$data'"
Eval.x(map, command)
}
所以在这里,命令是:x.b1.b2.b3_1 = 'test'
我们用 x
作为 map
另一种(比较难看)的方法是使用inject遍历map直到最后一个key,然后设置这个返回对象的最后一个key的值:
def setValue(Map map, String[] keys, String data) {
keys[0..-2].inject(map) { a, b -> a."$b" }."${keys[-1]}" = data
}
尽管如此,您还是应该小心评估代码....
例如,您可能会收到以下输入:
def name2 = "val = { -> println \"${System.properties.'user.name'}\" }.call(); def a"
计算表达式(对我而言):
x.val = { -> println "tim" }.call(); def a = 'test'
然后打印用户名...您可以看到如何调整它以从 Internet 下载文件并将其放在某人的计算机上...
如果可以...您应该避免这种情况...或者至少有严格的允许内容白名单
递归方法:
def setValue(def map, List keys, def data) {
return keys.size()>1 ?
setValue(map[keys[0]],keys.subList(1,keys.size()),data) :
map.put(keys[0],data)
}