我创建了一些混合方法。下面的代码和示例:
URL.metaClass.withCreds = { u, p ->
delegate.openConnection().tap {
setRequestProperty('Authorization', "Basic ${(u + ':' + p).bytes.encodeBase64()}")
}
}
URLConnection.metaClass.fetchJson = {
delegate.setRequestProperty('Accept', 'application/json')
delegate.connect()
def code = delegate.responseCode
def result = new JsonSlurper().parse(code >= 400 ? delegate.errorStream : delegate.inputStream as InputStream)
[
ok : code in (200..299),
body: result,
code: code
]
}
用法示例:
new URL("$baseUrl/projects/$name").withCreds(u, p).fetchJson().find {
it.ok
}?.tap{
it.repos = getRepos(it.key).collectEntries { [(it.slug): it] }
}
}
当我不使用 find()时,按预期,我的对象是包含这三个元素的地图。当我使用find it
是具有键ok
和值true
的Map.Entry
会产生此错误:
groovy.lang.MissingPropertyException: No such property: ok for class: java.util.LinkedHashMap$Entry
Possible solutions: key
当我写这篇文章时,我想到将地图视为可迭代地图,因此查看了我随后验证的每个条目。如何在整个地图上find
?我想要it.ok
,因为如果确实如此,我需要将其继续前进
答案 0 :(得分:1)
Groovy SDK中没有这样的方法。 Map.find()
在您调用方法所依据的地图的条目集上运行。根据您所定义的期望,我猜测您正在寻找一个函数,该函数使用给定的谓词测试map并在匹配谓词时返回该map。您可以通过Map.metaClass
添加一个执行此操作的函数(因为您已经向URL
和URLConnection
类添加了方法)。考虑以下示例:
Map.metaClass.continueIf = { Closure<Boolean> predicate ->
predicate(delegate) ? delegate : null
}
def map = [
ok : true,
body: '{"message": "ok"}',
code: 200
]
map.continueIf { it.ok }?.tap {
it.repos = "something"
}
println map
在此示例中,我们引入了一种新方法Map.continueIf(predicate)
,该方法测试map是否与给定谓词匹配,否则返回null
。运行上面的示例将产生以下输出:
[ok:true, body:{"message": "ok"}, code:200, repos:something]
如果不满足谓词,则map
不会被修改。
或者,对于更严格的设计,您可以使fetchJson()
方法返回具有相应的onSuccess()
和onError()
方法的对象,以便您可以更清楚地表示添加repos
当您获得成功的响应时,或者选择创建错误响应时,否则。
希望对您有帮助。