Spring Custom Configuration not populating properties with underscore - spring

I am trying to populate Custom class with properties. following is my Custom Properties class:
#Configuration
#ConfigurationProperties(prefix = "foo.bar")
public class CustomProperties{
private String PROPERTY_ONE;
private String propertyTwo;
//setters
//getters
}
and my properties in application.properties are:
foo.bar.PROPERTY_ONE=some text
foo.bar.PROPERTY_TWO=some other text
When I am trying to use value from CustomProperties this is what I gets:
customProperties.getPROPERTY_ONE() = null
customProperties.getPopertyTwo() = some other text
So I observed that if I have variable name with underscore(_) in it not populating the property value.
is there any way to get the value with variable having underscore?

Yes, it is 100% possible to get your configuration values.
It's all about the casing! Inside of CustomProperties simply name your first property propertyOne ... and refactor your getters/setters appropriately ... and you'll be good to go!
Spring's got the camel casing going on when translating the configuration fields to your Configuration classes/properties. So instead of matching the casing of your properties, follow the camel casing equivalent of the property name found in your configuration file.
Example: PROPERTY_ONE translates to propertyOne

Related

#ConfigurationProperties returns property placeholder instead of null

I have the following #ConfigurationProperties property holder:
#ConfigurationProperties(prefix = "custom.service")
public class CustomServicePropertyHolder {
private String name;
}
and my application.properties looks like this:
custom.service.name=${remote.service.name}
custom.service.....=...
custom.service.....=...
remove.service.name is an environment variable received in the runtime.
However, when remote.service.name was not provided, the value of the EtlConfigurationHolder.name is a string "${remote.service.name}".
How to make the property to return null instead of this placeholder string ?
I also encountered such a problem ... And it has been present for a long time
Unresolved Placeholder Validation for Spring Boot Configuration Properties
https://github.com/spring-projects/spring-boot/issues/4302
https://github.com/spring-projects/spring-boot/issues/1768
I found only one place where at least some solution is attached
https://davidagood.com/spring-boot-fail-on-missing-env-vars/

How to define a conditional property with a variable sub property name

I have a configuration property class that contains a map. The map is filled with values from a yml file. the structure looks like this.
config:
variable_sub_key_a:
key_a: 1234
key_b: 1234
variable_sub_key_b:
...
The configuration class looks like:
#Configuration
public class Configuration{
private Map<String, KEY> config= new HashMap<>();
}
I would like that the configuration class is only initialized by spring when the config element exists in the yml file. My problem is that a part of the property name can vary. So i can't use #ConditionalOnProperty. I tried it with different contidional-annotations but haven't found out how i could define a conditional that checks only that the property starts with config.* . Any hints how i can do this?

Using #Value annotation with Spring and SPeL

I am trying to find a way to do the following in my spring boot 1.5 application.
I have a variable who's value is dynamic meaning it comes in from an external system.
String name = "abc"; //gets set externally
I want to try and use the name's value to lookup my property file and see if there is a matching property defined. something like..
#Value("#{myClassName.name.concat('something')}")
String propertyValue;
Now my application.property file has the following property set
assume name has the value "abc"
property file contents:
abc.something:abcValue
Now, when i try to access the value of the variable propertyValue it gets set to the value abc.something and not abcValue.
I probably think I cannot use #Value with #{} to get to that, I was wondering if there was a way to to use #{} inside ${} so that I goes and fetches the property value after calculating the name of the property using #{}.
Let me know if you need more details please.
A bean life-cycle requires properties to be resolved at compile time. So, #Value requires constant parameter.
You can use Environment bean to access your properties programmatically.
import org.springframework.core.env.Environment;
#Service
public class Serivce {
#Autowired
private Environment environment;
public String getProperty(final String keyPart) {
String key = "build.your." + keyPart;
return environment.getProperty(key)
}
}
By the way you can use #('${spring.some.property}') in SpEL to access placeholder.
// This is valid access to property
#Value("#('${spring.some.property}')")
private String property;

Spring: #NestedConfigurationProperty List in #ConfigurationProperties

Hi I am trying to get the following configuration up and running.
#ConfigurationProperties(prefix="my")
public class Config {
#NestedConfigurationProperty
private List<ServerConfiguration> servers = new ArrayList<ServerConfiguration>();
public List<ServerConfiguration> getServers() {
return this.servers;
}
}
#ConfigurationProperties(prefix = "server")
public class ServerConfiguration {
private String name;
private String description;
}
So, I want to have multiple server configs nested in objects.
I tried setting the properties with the following properties file. I can see that the list is added up by items but the members of the server are never set (name, description)
my.servers[0].name=test
my.servers[0].server.name=test
my.servers[1].name=test
my.servers[1].server.name=test
To extend what Maciej said already.
#ConfigurationProperties should be set only on root objects (that is objects that are responsible to handle a given prefix. There is no need to annotated nested objects with it.
#NestedConfigurationProperty is only used by the meta-data generator (to indicate that a property is not a single value but something we should explore to generate additional meta-data. In the case of the List there isn't any finite amount of properties so the meta-data will have to stop at the list.
In any case you need a getter and a setter for each singular property. We don't do field binding and we require a public getter to avoid exposing unnecessary properties in the meta-data.
You need to add setters and getters to ServerConfiguration
You don't need to annotate class with nested properties with #ConfigurationProperties
There is a mismatch in names between ServerConfiguration.description and property my.servers[X].server.name=test

How do #value annotations work in Spring?

I've never worked with Spring before, and I've run into a configuration object that looks somewhat like this
public class Config {
#Value("${app.module.config1}")
private String config1;
#Value("${app.module.config2}")
private String config2
...
public String getConfig1() {
return config1;
}
...
Can anyone explain what is happening here? I'm assuming this is some type of code injection, but I can't find where these values are coming from!
They allow you to direct inject a Value from a properties file (system or declared property) in the variable. Using the util:properties tag you can add something like this in your applicationContext.xml
<util:properties id="message" location="classpath:com/your/program/resources/message.properties" />
Pointing for a properties file named "message.properties" with some content:
application.hello.message = Hello World!
And then, in your java source file, inject a direct value from this properties file using the #Value annotation:
#Value("#{message['application.hello.message']}")
private String helloWorldMessage;
#Value("${app.module.config1}")
This is part of the spring expression language where the spring framework would look for app.module.config1 JVM property from System.getProperties() and injects the value of that property into config1 attribute in that class. Please see this reference for more details in Spring 3.0.x and this reference for the current docs.

Resources