在groovy中使用evaluate时,我的代码中有错误吗?
我将值设置为嵌套贴图,所有键都存在,以下是我的代码:在groovy中使用evaluate时,我的代码中有错误吗?,groovy,evaluate,Groovy,Evaluate,我将值设置为嵌套贴图,所有键都存在,以下是我的代码: 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 = [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=‘测试’
我可以手动运行它并更改地图内容,但是当我使用evaluate时,出现了java.lang.NullPointerException错误:无法在null对象上获取属性“b2”,请告诉我代码有什么问题,非常感谢。您试图做的很难 一种方法是使用Eval.x,并将地图作为x传递: 这里的命令是:x.b1.b2.b3_1='test',我们用x作为map的值来计算它 另一个更难看的方法是使用inject遍历贴图直到最后一个键,然后设置此返回对象的最后一个键的值:
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)
}
您好,您的想法很好,但结果不是我想要的,我尝试了,返回值是B234。它返回地图中的旧值。并修改地图。你可以检查一下。我很抱歉这么长时间没有回复,你是对的,它成功地解决了我的问题,非常感谢!谢谢你们的回复,我尝试了你们的第一种方法,它很有效,正如你们所说,它看起来有点难看,所以我用递归方法来解决它,谢谢你们的帮助!
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)
}