问题
Enum
public enum Property {
A,
AB,
ABC;
}
Field
@Value("${custom.property}")
protected Property property;
application.properties (lower case)
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.
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.
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.
回答1:
@Value
and @ConfigurationProperties
features do not match. I couldn't stress enough how @ConfigurationProperties
is superior.
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 easily get auto-completion in your IDE for your own keys.
And finally, the relaxed binding described in the doc only applies to @ConfigurationProperties
. @Value
is a Spring Framework feature and is unaware of relaxed binding. We intend to make that more clear in the doc.
TL;DR abc
works with @ConfigurationProperties
but won't with @Value
.
回答2:
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.
Just use the correct case in your configuration properties.
回答3:
A problem with ConfigurationPropertis (afaik) is that you cannot use constructor injection, and your class has to be mutable.
A workaround (or hack if you like) would be to use SpEL to uppercase the property before looking it up, like this:
@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
回答4:
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!
来源:https://stackoverflow.com/questions/35565758/spring-boot-bind-value-to-enum-case-insensitive