当前位置: 首页 > 知识库问答 >
问题:

奇怪的行为

公西翼
2023-03-14

我有以下代码来解析一个JSON文件:

@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文件:

{
  "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"]
        }
      ]
    }
  ]
}

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

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()中的哪个代码部分抛出了这个异常。令人惊讶的是,那里的所有代码都正常执行:没有抛出异常,也没有返回结果I except。

更让我惊讶的是,当我稍微改变第一种方法的代码时,它可以在不产生异常的情况下工作。

@Override
Map<String, Configuration> readConfiguration() {
    Object configurationFile = readConfigurationFile()
    configurationFile.schemas.each { schemaProtectionInformation ->
        processing(schemaProtectionInformation)
    }
    println "test 2"
}

我不知道println方法如何改变那里的任何东西。当然,不一定是println方法可以解决问题。所以如果我做这样的事情:

@Override
Map<String, Configuration> readConfiguration() {
    Object configurationFile = readConfigurationFile()
    configurationFile.schemas.each { schemaProtectionInformation ->
        processing(schemaProtectionInformation)
    }
    test()
}

void test() {

}

它也可以工作(不会抛出任何异常)。我不知道为什么在处理json文件后添加一些额外的代码会有什么改变。

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

@Override
Map<String, Configuration> readConfiguration() {
    Object configurationFile = readConfigurationFile()
    configurationFile.schemas.each { schemaProtectionInformation ->
        //processing(schemaProtectionInformation)
    }
}

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

我将非常感谢你的投入。

共有2个答案

呼延原
2023-03-14

哇,对不起。这是一个新手的错误。太糟糕了,我没有这门课的单元测试,因为我会更快地发现缺失的部分。

显然缺失的部分是返回关键字。现在的代码看起来像这样:

@Override
Map<String, Configuration> readConfiguration() {
    Object configurationFile = readConfigurationFile()
    configurationFile.schemas.each() { schemaProtectionInformation ->
        processSchemaDetailsFromFile(schemaProtectionInformation)
    }
    return schemasConfigurations
}

并且无任何问题地工作。

如果我没记错的话,这段代码是从reloadConfiguration()不返回值的代码演变而来的。然后可能我改变了返回类型,但是忘记了添加一个显式的返回语句。由于groovy不允许使用return关键字,所以它没有抱怨,而是尝试返回一些list,然后失败了,因为这个方法返回的指定类型的值是map。

井。。。我责怪睡眠不足。

公风史
2023-03-14

在Groovy中,返回是隐式的,它是函数的最后一个语句。所以你的代码相当于:

@Override
Map<String, Configuration> parseJson() {
    Object configurationFile = readConfigurationFile()
    return configurationFile.schemas.each { schemaProtectionInformation ->
        processing(schemaProtectionInformation)
    }
}

函数的作用是:返回被调用的元素。在您的情况下,< code >模式。然而,schema是一个集合,而不是一个映射:您看到的是ClassCastException。您的代码相当于:

@Override
Map<String, Configuration> parseJson() {
    Object configurationFile = readConfigurationFile()
    configurationFile.schemas.each { schemaProtectionInformation ->
        processing(schemaProtectionInformation)
    }
    return configurationFile.schemas
}

当您在此语句之后添加某些内容时,您只是在创建另一个隐式返回。您应该使用显式返回配置File

 类似资料:
  • 问题内容: 我在GregorianCalendar类中遇到一个奇怪的行为,我想知道我是否真的做得不好。 仅当初始化日期的月份的实际Maximum大于我将日历设置为的月份时,才追加此值。 这是示例代码: 我知道问题是由于日历初始化日期是31天(可能是5月),与设置为2月(28天)的月份混淆了。修复很容易(只需在设置年和月之前将day_of_month设置为1),但是我想知道这确实是想要的行为。有什么

  • 问题内容: 我正在为一个问题而苦苦挣扎,我不明白为什么它不起作用。如何通过将变量传递并转换为? 为什么在顶部代码段中不起作用,但在行下方的底部代码段中起作用? 唯一的区别似乎是添加了一个额外的变量,该变量也被键入为? 问题答案: 该是一种原始类型,同时是一个普通的Java类。您不能在原始类型上调用方法。但是该方法在上可用,如javadoc中所示 有关这些原始类型的更多信息,请参见此处

  • 问题内容: 为什么的到哪里去了? 问题答案: 删除任何字符,并从字符串的开头和结尾。

  • 问题内容: 我认为这是一个正常程序,但这是我得到的输出: 有人可以向我解释一下吗? 问题答案: 这是有据可查的PHP行为,请参阅php.net的foreach页面上的警告。 警告 即使在 foreach 循环之后,仍保留 $ value的 引用和最后一个数组元素。建议通过unset()销毁它。 __ 编辑 尝试逐步了解此处实际发生的情况

  • 问题内容: 我有上面的代码,但我不知道为什么会产生 而不是 非常感谢 问题答案: 使用量词来匹配1个或多个空格,而不是:- 表示匹配0个或多个空格,并且将在每个字符之前匹配一个空字符,并由一个空格代替。

  • 我正在Glassfish 4.1上制作一个Java EE 7应用程序(war) 该应用程序是一个简单的CRUD应用程序 为了测试CRUD操作,我制作了一个Java SE客户端(使用Jersey2客户端api)。奇怪的行为是HTTP POST创建没有检测到对象的一个字段: 我有一个“birthDate”属性,它在服务器端总是为“null”<我不明白为什么会发生这种情况以及如何解决? 以下是我在服务器