【问题标题】:Unable to map application properties to object with dynamic property key无法将应用程序属性映射到具有动态属性键的对象
【发布时间】:2020-01-07 01:10:56
【问题描述】:

我正在尝试按值获取应用程序属性对象,我已经在 J​​ava 中这样做了,但由于某种原因使用 Kotlin 我无法做到。

所以基本上我所拥有的是如下所示的应用程序属性列表:

ee.car.config.audi.serial=1
ee.car.config.audi.base=platform1

ee.car.config.bmw.serial=2
ee.car.config.bmw.base=platform2

所以你可以看到汽车标识符(奥迪、宝马、标致等)是动态的,我只需要通过序列值来获取代表特定汽车的对象并通过汽车钥匙(奥迪、宝马)来获取所有其他属性。

我所做的很简单,我创建了这样的配置属性类:

@Configuration
@ConfigurationProperties(prefix = "ee.car")
data class FesEngineKeys(
        val config: HashMap<String, EeCarConfigParam> = HashMap()
) {
    fun getOrDefaultEEConfig(engineKey: String): EeCarConfigParam? {
        return config.getOrDefault(engineKey, config["audi"])
    }

然后对象映射到动态值后的键:

data class EeCarConfigParam {
        var serial: String,
        var base: String
}

但这里的问题是,在 FesEngineKeys 类中,config 属性为空,看起来 EeCarConfigParam 无法映射。

另一个有趣的部分是当我改变时:

val config: HashMap<String, EeCarConfigParam> = HashMap() to
val config: HashMap<String, String> = HashMap()

然后我可以看到配置参数填充了所有值。

这段代码已经在 J​​ava 中运行,看起来像这样:

@Configuration
@Getter
@Setter
@ConfigurationProperties(prefix = "ee.car")
public class FESEngineKeys {

    private Map<String, EeCarConfigParam> config = new HashMap<>();

    public EeCarConfigParam getOrDefaultEEConfig(String engineKey) {
        return config.getOrDefault(engineKey, config.get("audi"));
    }

    public EeCarConfigParam findBySerial(String serial) {
        return config.values().stream().filter(cfg -> cfg.getSerial().equalsIgnoreCase(serial)).findFirst().orElse(null);
    }

}


@Data
public class EeCarConfigParam {
    private String serial;
    private String base;
}

我真的不知道为什么在 Kotlin 案例中它不起作用,我可能犯了一些非常基本的错误,如果有人能解释这里发生的事情,我将不胜感激

【问题讨论】:

  • 两件事,我会照顾:首先让 EeCarConfigParam 成为一个数据类(用于等于和哈希码).. 第二个在 kotlin 中注入地图,而在 java 中它是一个属性.. 改变地图财产?我猜 Map 是 spring 默认值,可以注入。这只是猜测,也许我错了
  • 它已经是数据类,我的错误我没有包括有问题的(现在已编辑)。你是什​​么意思改变 map 到 property ?可以举个例子吗?
  • 数据类 FesEngineKeys() { private val config: HashMap = HashMap() ....
  • 还是不行
  • 公开配置映射?

标签: java spring-boot kotlin


【解决方案1】:

好的,我明白了。 据此:https://docs.spring.io/spring-boot/docs/2.0.x/reference/html/boot-features-kotlin.html对你想要的支持非常有限。

我让它像那样工作 - 不太好:-( :

@ConfigurationProperties(prefix = "ee.car")
class FesEngineKeyProperties() {

    var config: MutableMap<String, EeCarConfigParam?>? = mutableMapOf()

    fun getBase(serial: String): String {
        if(config == null) return ""
        return config!!["audi"]?.base ?: ""
    }
}


class EeCarConfigParam() {
    lateinit var serial: String
    lateinit var base: String
}

@SpringBootApplication
@EnableConfigurationProperties(FesEngineKeyProperties::class)
class SandboxApplication

fun main(args: Array<String>) {
    runApplication<SandboxApplication>(*args)
}

【讨论】:

  • 感谢您的努力和帮助,但我能够以更干净的方式做到这一点,基本上我所做的是,我创建了“普通”Java 类而不是 Kotlin 类,一切都是无需任何额外或特殊代码即可工作,明天我将粘贴我的解决方案,有人可能会觉得它有用。
【解决方案2】:

我能够处理这个问题,它在某种程度上与 kotlin 相关,因为曾经当 i 而不是这个:

data class EeCarConfigParam {
        var serial: String,
        var base: String
}

使用“norma”Java 类,一切都开始工作了,所以我的问题中的所有代码都保持不变,唯一的区别是:我创建了这样的 Java 类,而不是 Kotlin EeCardConfigParam:

public class EeCarConfigParam {
    private String publicUrl;
    private String base;
}

注意:使用所有默认的 getter、setter、equals、hash 和 toString 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-18
    • 1970-01-01
    • 2015-08-13
    • 1970-01-01
    • 1970-01-01
    • 2017-03-16
    相关资源
    最近更新 更多