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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35565758/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 16:50:19  来源:igfitidea点击:

Spring Boot bind @Value to Enum case insensitive

javaspringspring-bootenumsspring-properties

提问by Mikhail Kholodkov

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, abcany pattern should work.

有没有办法绑定不区分大小写的值?像ABCAbcAbCabc任何模式都应该工作。

NOTE: I saw this question - Spring 3.0 MVC binding Enums Case Sensitivebut 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 binding Enums Case Sensitive但在我的例子中我有超过 10 个枚举/值(并且期望有更多)类并且实现 10 个不同的自定义属性绑定器会很痛苦,我需要一些通用的解决方案.

采纳答案by Stephane Nicoll

@Valueand @ConfigurationPropertiesfeatures do not match. I couldn't stress enough how @ConfigurationPropertiesis superior.

@Value@ConfigurationProperties功能不匹配。我怎么强调都不@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). Second, the meta-data support means that you can very easilyget auto-completion in your IDE for your own keys.

首先,你可以在一个简单的 POJO 中设计你的配置,你可以在任何你想要的地方注入它(而不是在注释中使用表达式,你可以很容易地因打字错误而中断)。其次,元数据支持意味着您可以非常轻松地在 IDE 中为您自己的密钥自动完成

And finally, the relaxed binding described in the doc only applies to @ConfigurationProperties. @Valueis a Spring Framework feature and is unaware of relaxed binding. We intend to make that more clear in the doc.

最后,文档中描述的宽松绑定仅适用于@ConfigurationProperties. @Value是 Spring Framework 的一个特性,不知道松散绑定。我们打算在文档中更清楚地说明这一点

TL;DR abcworks with @ConfigurationPropertiesbut won't with @Value.

TL; DRabc可与@ConfigurationProperties但不会@Value

回答by jonny.l

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!

..虽然这确实打破了枚举的原则!

回答by Morten Berg

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

@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