简体   繁体   English

Spring Boot绑定@Value到Enum不区分大小写

[英]Spring Boot bind @Value to Enum case insensitive

Enum 枚举

public enum Property {
    A,
    AB,
    ABC;
}

Field 领域

@Value("${custom.property}")
protected Property property;

application.properties (lower case) application.properties (小写)

custom.property=abc

When I'm running application I have an error: 当我运行应用程序时,我有一个错误:

Cannot convert value of type [java.lang.String] to required type [com.xxx.Property]: no matching editors or conversion strategy found. 无法将[java.lang.String]类型的值转换为必需的类型[com.xxx.Property]:找不到匹配的编辑器或转换策略。

Whereas (upper case): 鉴于(大写):

custom.property=ABC

Works fine. 工作良好。

Is there a way to bind the value case insensitive? 有没有办法绑定值不区分大小写的值? Like ABC , Abc , AbC , abc any pattern should work. ABCAbcAbCabc任何模式都应该有效。

NOTE: I saw this question - Spring 3.0 MVC binding Enums Case Sensitive but in my case I have over 10 enums/values (and expect to have more) classes and to implement 10 different custom property binders would be painful, I need some generic solution. 注意:我看到了这个问题 - Spring 3.0 MVC绑定Enums区分大小写,但在我的情况下,我有超过10个枚举/值(并期望有更多)类并实现10种不同的自定义属性绑定器会很痛苦,我需要一些通用的解决方案。

@Value and @ConfigurationProperties features do not match. @Value@ConfigurationProperties功能不匹配。 I couldn't stress enough how @ConfigurationProperties is superior. 我无法强调@ConfigurationProperties如何优越。

First, you get to design your configuration in a simple POJO that you can inject wherever you want (rather than having expressions in annotation that you can easily break with a typo). 首先,您可以在一个简单的POJO中设计您的配置,您可以在任何地方注入(而不是在注释中使用表达式,您可以轻松打破拼写错误)。 Second, the meta-data support means that you can very easily get auto-completion in your IDE for your own keys . 其次,元数据支持意味着您可以非常轻松地 在IDE中自行完成自己的密钥

And finally, the relaxed binding described in the doc only applies to @ConfigurationProperties . 最后,doc中描述的宽松绑定仅适用于@ConfigurationProperties @Value is a Spring Framework feature and is unaware of relaxed binding. @Value是一个Spring Framework功能,并不知道轻松绑定。 We intend to make that more clear in the doc . 我们打算在文档中更清楚地说明

TL;DR abc works with @ConfigurationProperties but won't with @Value . TL; DR abc@ConfigurationProperties但不与@Value一起@Value

The values are case-sensitive (consider keys or passwords injected from the environment), and the relaxed binding applies only to the keys. 值区分大小写(考虑从环境注入的密钥或密码),宽松绑定仅适用于密钥。 Java enum names are also case-sensitive ( A and a are distinct values), and you wouldn't want to squash case. Java枚举名称也区分大小写( Aa是不同的值),您不希望压缩大小写。

Just use the correct case in your configuration properties. 只需在配置属性中使用正确的大小写即可。

A problem with ConfigurationPropertis (afaik) is that you cannot use constructor injection, and your class has to be mutable. ConfigurationPropertis(afaik)的一个问题是你不能使用构造函数注入,并且你的类必须是可变的。

A workaround (or hack if you like) would be to use SpEL to uppercase the property before looking it up, like this: 一个变通方法(或者如果你愿意,也可以使用hack)在查找之前使用SpEL来大写属性,如下所示:

@Value("#{'${custom.property}'.toUpperCase()}") Property property

This should work since enums instances are constants, and should always be defined in uppercase: https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html 这应该有效,因为枚举实例是常量,并且应始终以大写形式定义: https//docs.oracle.com/javase/tutorial/java/javaOO/enum.html

In a practical world, this works.... 在实际的世界中,这是有效的......

public enum Property {
    A, a
    AB, ab,
    ABC, abc,
    ABCD, abcd,
    ABCDE, abcde; 

    public boolean isA() {
        return this.equals(A) || this.equals(a);
    }

    public boolean isAB() {
        return this.equals(AB) || this.equals(ab);
    }

    ...etc...

}

..although this does break the principle of the enum! ..这确实打破了枚举的原则!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM