The application.properties
customer.metadata.intKey=123
customer.metadata.booleanKey=true
The CustomerProperties.java
@ConfigurationProperties(prefix = "customer")
public class CustomerProperties {
private Map<String, Object> metadata;
public Map<String, Object> getMetadata() {
return metadata;
}
public void setMetadata(Map<String, Object> metadata) {
this.metadata = metadata;
}
}
The Application.java
@SpringBootApplication
@EnableConfigurationProperties(CustomerProperties.class)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public ApplicationRunner runner(CustomerProperties customerProperties) {
return args -> {
// Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
Integer value = (Integer) customerProperties.getMetadata().get("intKey");
System.out.println(value);
};
}
}
The Error stack
java.lang.IllegalStateException: Failed to execute ApplicationRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:778) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:765) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:322) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
at com.yuhb.gateway.Application.main(Application.java:17) [classes/:na]
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at com.yuhb.gateway.Application.lambda$runner$0(Application.java:23) [classes/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:775) [spring-boot-2.2.2.RELEASE.jar:2.2.2.RELEASE]
... 5 common frames omitted
Comment From: wilkinsona
There's no type information to lose as there's no type information in a properties file – the keys and values are all strings. Your metadata map doesn't constrain the type of its values (it's using Object
) so there's no way of knowing what type you want them to have. As a result, the values are left as strings.
If the map constrained the type, for example by being a Map<String, Integer>
, each value would be converted to an Integer
automatically. As you are mixing types this won't help in this specific case. Instead, you may want to consider replacing the map with a rich type with intKey
and booleanKey
properties that are typed as int
and boolean
respectively.
If you have any further questions, please follow up on Stack Overflow or Gitter. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.