";“groovy”;访问嵌套字段的方法
拿这些东西";“groovy”;访问嵌套字段的方法,groovy,Groovy,拿这些东西 class Obj1 { Obj2 obj2 } class Obj2 { Obj3 obj3 } class Obj3 { String tryme } 现在,这个模型上的Crud操作是通过angularjs应用程序进行的。angular应用程序发回更改的字段。例如,它可能会发送 [ { "jsonPath": "/obj2/obj3/tryme", "newValue": "New Name" } ] 那么,使用
class Obj1 {
Obj2 obj2
}
class Obj2 {
Obj3 obj3
}
class Obj3 {
String tryme
}
现在,这个模型上的Crud操作是通过angularjs应用程序进行的。angular应用程序发回更改的字段。例如,它可能会发送
[
{
"jsonPath": "/obj2/obj3/tryme",
"newValue": "New Name"
}
]
那么,使用groovy,有没有一种简单的方法来访问这个嵌套字段呢?我可以用java反射来实现,但这需要很多代码。如果不是pojo的,这是一个mongodb,所以我想我可以用json slurp来实现,如果更简单的话,我只是不知道。任何建议都将不胜感激
因此,我要展示我迄今为止发现的解决方案的问题。拿着这个
Obj1 a = new Obj1()
使用此的编辑对象
[
{
"jsonPath": "/obj2/obj3/tryme",
"newValue": "New Name"
}
]
在执行pojo路由时,查找obj2的空字段不是问题。问题是我无法知道它是什么类型,以便初始化字段并继续遍历树
请避免Groovy是无类型的,我们这里不使用def
,所有内容都需要静态类型
因此,我也从JsonSlurp方面尝试了这一点,只是将pojo全部删除。但即使这样也有问题,因为我似乎又回到了迭代地图的过程中去了。同样的问题,更容易解决
class MongoRecordEditor {
def getProperty(def object, String propertyPath) {
propertyPath.tokenize('/').inject object, {obj, prop ->
def retObj = obj[prop]
if (retObj == null){
println obj[prop].class
}
}
}
void setProperty(def object, String propertyPath, Object value) {
def pathElements = propertyPath.tokenize('/')
def objectField
if (pathElements.size() == 1){
objectField = pathElements[0]
} else {
objectField = pathElements[0..-2].join('/')
}
Object parent = getProperty(object, objectField)
parent[pathElements[-1]] = value
}
}
是许多想法的结晶。现在运行def retObj=obj[prop]
是小菜一碟。问题是,如果字段没有初始化,那么retObj
总是空的,因此我无法得到初始化它的类型
是的,我知道,一旦我弄明白如何使它工作,我就会把它打出来。也许是这样的
class Obj1 {
Obj2 obj2
}
class Obj2 {
Obj3 obj3
}
class Obj3 {
String tryme
}
def a = new Obj1(obj2: new Obj2(obj3: new Obj3(tryme:"test")))
for (value in "obj2/obj3/tryme".split("/")) {
a = a?."${value}"
}
println a
您可以创建trait,然后让Obj1使用它:
trait DynamicPath {
def get(String path) {
def target = this
for (value in path.split("/")) {
target = target?."${value}"
}
target
}
}
class Obj1 implements DynamicPath{
Obj2 obj2
}
println a.get("obj2/obj3/tryme");
不确定这是否是你想要的。。。它依赖于具有默认构造函数的对象,可能有更好的方法来实现它 撇开这些警告不谈,考虑到你有:
import groovy.transform.*
import groovy.json.*
@ToString
class Obj1 {
Obj2 obj2
}
@ToString
class Obj2 {
Obj3 obj3
}
@ToString
class Obj3 {
String tryme
}
def changeRequest = '''[
{
"jsonPath": "/obj2/obj3/tryme",
"newValue": "New Name"
}
]'''
然后,可以这样定义操纵器:
def change(Object o, String path, String value) {
Object current = o
String[] pathElements = path.split('/').drop(1)
pathElements[0..-2].each { f ->
if(current."$f" == null) {
current."$f" = current.class.declaredFields.find { it -> f == it.name }?.type.getConstructor().newInstance()
}
current = current."$f"
}
current."${pathElements[-1]}" = value
o
}
就这样说吧
def results = new JsonSlurper().parseText(changeRequest).collect {
change(new Obj1(), it.jsonPath, it.newValue)
}
要提供包含一个新Obj1实例的列表,请执行以下操作:
[Obj1(Obj2(Obj3(New Name)))]
我一直在做一些类似的工作,基于此,问题是未初始化的字段。当我访问一个未初始化的字段时,我无法确定它应该是什么类型。我现在正在用json slurper进行实验,想如果我接受我的pojo,slurp它,更新它,回滚到pojo。如果我能做到这一点,我可能会一起消除pojo,或者干脆将其用于验证。还不是很确定。你能不能只用
?。
运算符?我不熟悉那个,我是说我知道的点,但问题是,它是做什么的?它是。更新了我的答案以使用它。好的,我明白这是在做什么了。还有我的二传手问题。如果obj2为null,我找不到初始化它的方法。这里的方法1:?我现在正在尝试类似的方法,但是我对未初始化的字段有问题。我现在正在尝试json方法。我即将放弃,转而使用传统的地图迭代器地图。我想用groovy做这件事会更容易,这让我明白。它应该是。。。你能编辑你的问题来表达你的意思吗?第二天早上,当我手边有一台电脑时,我会看一看:-)