首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Groovy + JsonSlurper奇怪行为

Groovy + JsonSlurper奇怪行为
EN

Stack Overflow用户
提问于 2016-03-04 21:31:17
回答 2查看 2.9K关注 0票数 2

下面是解析JSON文件的代码:

代码语言:javascript
复制
@Override
Map<String, Configuration> parseJson() {
    Object configurationFile = readConfigurationFile()
    configurationFile.schemas.each { schemaProtectionInformation ->
        processing(schemaProtectionInformation)
    }
}

private Object readConfigurationFile() {
    InputStream is = getClass().getClassLoader().getResourceAsStream("test.json")
    BufferedReader reader = new BufferedReader(new InputStreamReader(is))
    return new JsonSlurper().parse(reader)
}

要处理以下JSON文件:

代码语言:javascript
复制
{
  "schemas": [
    {
      "name": "plan_pm_test",
      "protectedDimensions": [
        {
          "name": "dActivityWbs",
          "usedToSecureFactTable": true,
          "aliasInFactTable": "PLAN_WBS",
          "levels" : ["LEVEL_1_ID","LEVEL_2_ID","LEVEL_3_ID","LEVEL_4_ID","LEVEL_5_ID","LEVEL_6_ID","LEVEL_7_ID","LEVEL_8_ID","LEVEL_9_ID"]
        },
        {
          "name": "dResponsibleOrganicUnit",
          "usedToSecureFactTable": true,
          "aliasInFactTable": "RES_ORG_UNIT",
          "levels" : ["ID","LEVEL_1_ID","LEVEL_2_ID"]
        },
        {
          "name": "dContributionOrganicUnit",
          "usedToSecureFactTable": true,
          "aliasInFactTable": "CON_ORG_UNIT",
          "levels" : ["ID","LEVEL_1_ID","LEVEL_2_ID"]
        }
      ]
    }
  ]
}

如果执行此代码,将收到以下错误:

代码语言:javascript
复制
Cannot cast object '[{name=plan_pm_test, protectedDimensions=[{aliasInFactTable=PLAN_WBS, levels=[LEVEL_1_ID, LEVEL_2_ID, LEVEL_3_ID, LEVEL_4_ID, LEVEL_5_ID, LEVEL_6_ID, LEVEL_7_ID, LEVEL_8_ID, LEVEL_9_ID], name=dActivityWbs, usedToSecureFactTable=true}, {aliasInFactTable=RES_ORG_UNIT, levels=[ID, LEVEL_1_ID, LEVEL_2_ID], name=dResponsibleOrganicUnit, usedToSecureFactTable=true}, {aliasInFactTable=CON_ORG_UNIT, levels=[ID, LEVEL_1_ID, LEVEL_2_ID], name=dContributionOrganicUnit, usedToSecureFactTable=true}]}]' with class 'java.util.ArrayList' to class 'java.util.Map' due to: groovy.lang.GroovyRuntimeException: Could not find matching constructor for: java.util.Map(groovy.json.internal.LazyMap)
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '[{name=plan_pm_test, protectedDimensions=[{aliasInFactTable=PLAN_WBS, levels=[LEVEL_1_ID, LEVEL_2_ID, LEVEL_3_ID, LEVEL_4_ID, LEVEL_5_ID, LEVEL_6_ID, LEVEL_7_ID, LEVEL_8_ID, LEVEL_9_ID], name=dActivityWbs, usedToSecureFactTable=true}, {aliasInFactTable=RES_ORG_UNIT, levels=[ID, LEVEL_1_ID, LEVEL_2_ID], name=dResponsibleOrganicUnit, usedToSecureFactTable=true}, {aliasInFactTable=CON_ORG_UNIT, levels=[ID, LEVEL_1_ID, LEVEL_2_ID], name=dContributionOrganicUnit, usedToSecureFactTable=true}]}]' with class 'java.util.ArrayList' to class 'java.util.Map' due to: groovy.lang.GroovyRuntimeException: Could not find matching constructor for: java.util.Map(groovy.json.internal.LazyMap)
    at cern.ais.datawarehouse.baserver.mondriansecurity.common.schemaprotectionconfiguration.JsonResourceFileConfigurationRepositoryPopulator.readConfiguration(JsonResourceFileConfigurationRepositoryPopulator.groovy:23)
    at cern.ais.datawarehouse.baserver.mondriansecurity.common.schemaprotectionconfiguration.JsonResourceFileConfigurationRepositoryPopulatorTest.tes(JsonResourceFileConfigurationRepositoryPopulatorTest.groovy:12)

因此,当然,我开始一步一步地调试应用程序,以查看part processing()中的哪一部分代码会抛出此异常。令人惊讶的是,那里的所有代码都正常执行:不抛出异常并返回结果。

更让我吃惊的是,当我稍微修改第一种方法的代码时,它可以正常工作,而不会产生异常。

代码语言:javascript
复制
@Override
Map<String, Configuration> readConfiguration() {
    Object configurationFile = readConfigurationFile()
    configurationFile.schemas.each { schemaProtectionInformation ->
        processing(schemaProtectionInformation)
    }
    println "test 2"
}

我不知道println方法如何改变那里的任何东西。当然,它不一定非得是println方法才能做到这一点。所以如果我做这样的事

代码语言:javascript
复制
@Override
Map<String, Configuration> readConfiguration() {
    Object configurationFile = readConfigurationFile()
    configurationFile.schemas.each { schemaProtectionInformation ->
        processing(schemaProtectionInformation)
    }
    test()
}

void test() {

}

它也会起作用(不抛出任何费用)。我不知道为什么在处理json文件之后有一些额外的代码应该在这里做任何更改。

刚才我实际上已经注释掉了处理方法,所以方法主体如下所示。

代码语言:javascript
复制
@Override
Map<String, Configuration> readConfiguration() {
    Object configurationFile = readConfigurationFile()
    configurationFile.schemas.each { schemaProtectionInformation ->
        //processing(schemaProtectionInformation)
    }
}

即使我收到了同样的例外。因此,该错误与处理方法的实现无关。

我非常感谢你的意见。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-03-04 21:48:46

在Groovy中,return是隐式的,它是函数的最后一条语句。因此,您的代码相当于:

代码语言:javascript
复制
@Override
Map<String, Configuration> parseJson() {
    Object configurationFile = readConfigurationFile()
    return configurationFile.schemas.each { schemaProtectionInformation ->
        processing(schemaProtectionInformation)
    }
}

each函数返回被调用的元素。以你为例,schemas。但是,模式是一个集合,而不是一个映射:您可以看到ClassCastException。您的代码等效于:

代码语言:javascript
复制
@Override
Map<String, Configuration> parseJson() {
    Object configurationFile = readConfigurationFile()
    configurationFile.schemas.each { schemaProtectionInformation ->
        processing(schemaProtectionInformation)
    }
    return configurationFile.schemas
}

当您在该语句之后添加一些内容时,您只是在创建另一个隐式return。您应该使用显式return configurationFile

票数 1
EN

Stack Overflow用户

发布于 2016-03-04 21:48:29

哇,对不起。真是个菜鸟的错误。糟糕的是,我没有为这个类进行单元测试,因为我会更快地发现缺少的部分。

显然,缺少的部分是一个返回关键字。现在的代码如下所示:

代码语言:javascript
复制
@Override
Map<String, Configuration> readConfiguration() {
    Object configurationFile = readConfigurationFile()
    configurationFile.schemas.each() { schemaProtectionInformation ->
        processSchemaDetailsFromFile(schemaProtectionInformation)
    }
    return schemasConfigurations
}

而且没有任何问题。

如果我的内存正常的话,这段代码是从reloadConfiguration()没有返回值的代码演变而来的。然后,我可能更改了返回类型,但忘记添加显式返回语句。由于groovy允许没有返回关键字,所以它没有抱怨,试图返回一些列表,然后失败,从而导致此方法返回指定类型的值为map。

好吧..。我把这归咎于睡眠不足。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35806406

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档