Injecting values into Hashmap using java Spring - java

I was able to use java Spring annotation to inject key values pair into the hashmap as follows
validationError.properties file
errorcode.map={\
"default.labOrder.oneservice": "AAAAAA", \
"default.labOrder.patient.firstName": "BBBBB", \
}
I able to use the following code to inject the values into my hashmap as follows
#Value("#{${errorcode.map}}")
private Map<String, String> errorNumberMap;
However if I have a property file with the following values
errorcode.map={\
"LAB": "AAAAAA, BBBB, CCCC", \
"ECP": "AAAAAA, BBBB, CCCC", \
}
and a map Hashmap<AccessType, List> preserveMap = new HashMap() where AccessType is an enum. Does spring has any annotation that will populate my preserveMap value?
Thanks!

Mapping properties directly into bean fields only support simple basic mappings between properties and field values.
Using a configuration object gives more options and can do this kind of tricks and is also more readable.
https://www.baeldung.com/configuration-properties-in-spring-boot

Related

Validating HashMap keys once Bean method with #ConfigurationProperties initialized

I am new to String Boot and I am trying to parse property from application.properties into HashMap.
This is how I store Map in application.properties for good readability:
my.map.property.key0=value01,value02
my.map.property.key1=value11,value12
In my properties class I define a Bean with #ConfigurationProperties annotation:
#Bean
#ConfigurationProperties(prefix="my.map.property")
public Map<String, Set<String>> myMap() {
return new HashMap<>();
}
This works fine and to get that HashMap I can just Autowire that bean
#Autowired
Map<String, Set<String>> myMap
The problem is that it's very easy to mess up with correct Map keys in properties file and I want to validate keys to check if they match some Enum values.
Custom Enum validator is not working in this case, so I am thinking maybe I need to use Listeners or something else to do validation. Does anybody have any ideas on the best way to validate HashMap keys once myMap is initialized?

Spring Boot/YAML: How to read a map of Strings to Lists?

I have a property that looks like:
#Value(...)
Map<String, List<String>> classToMethods;
I want to populate this map via my application.yml in a Spring Boot application via the #Value("...") annotation. Some sample values are:
"java.lang.Double" => ["parseDouble", "toString"]
"java.lang.String" => ["toUpperCase"]
How do I represent this in my application.yml file? Also, I would like to put placeholder for environmentally injected values from our deployment tool. So for example, I currently have:
some:
property: ${ENV_VALUE:default_value_if_no_env}
Basically, this is the syntax I use for injecting values for the specific environment(value for ENV_VALUE varies for each environment). I am looking for a way to format the YML map such that this kind of environment replacements are also possible.
Alternative I am thinking of is just creating a String and manually parsing it during constructor injection but would like to avoid if possible.

Getting a map property from environment variable with Spring

I'm creating a microservice with Spring Boot that uses some properties loaded both with #Value and #ConfigurationProperties. Those properties will have default values defined in the application.yaml but I want to override them with environment variables. I've manage to do it with almost every basic property type but I'm unable with maps.
This is the code that retrieves the property, so the map is found in configuration.map:
#Data
#ConfigurationProperties(prefix = "configuration")
public class MapConfig{
private Map<String, Object> map;
}
The default values I have in the application.yaml are:
configuration:
map:
a: "A"
b: 2
c: true
This works fine and I get a map containing those key-value entries. Problem comes when I try to initialize the map with the environment variables. I've tried with multiples variants of CONFIGURATION_MAP='{aa:"aa", bb:12, cc:true}' and every time I start the application I get the default values defined in application.yaml but no trace of the environment map.
I also tried adding variables like CONFIGURATION_MAP_AA='HELLO' and I was able to put new values in my map. However all I can do is adding information but the default values I wrote in the yaml are still there. In this case I'm getting:
{
"aa": "HELLO",
"a": "A",
"b": 2,
"c": true
}
This isn't the behavior I'm looking for. I want to completely override the default map instead of adding new info. It also has the problem that keys added this way are always transformed to lowercase so I can't override keys with camelCase. And values are also casted to strings even when my map is <String,Object>.
Can anyone tell me how to properly initialize maps with environment variables or point me in the right direction? Thanks a lot!
The problem is the order in which the properties are been loaded.
Have a look at this doc that explains the loading order. I don't know if it will be
useful for your scenario but you can try creating a profile (for example application-other.yml) and load this. It will load after the application.yml
The cast is coming from the most general type in your list. In the end all three "name, 1, true" can be Strings. I can't think of a way of loading Object but you can recast your String on what you like ( if its needed. ) Else break it into multiple maps that are type specific ( Map<String,String> , Map<String,Boolean>, Map<String,Integer> )

How to get the map values from "yml" file as a Map?

I have a "details.yml" file, considering all the setting for getting all values from "yml.file" is done. But I am unable to store Map values into
"Map"
Here is my "details.yml" file below
details:
company:XYZ
values:
name: Manish
last: Raut
And in my class file i am able to get the values of "company" from yml file using #Value("${company}")
#Component
#EnableConfigurationProperties
#ConfigurationProperties(prefix = "details")
public class abcd() {
#Value("${company}")
String company;
#Value("${values}")
Map<String, String> values =new HashMap<String, String>();
...............................
}
i am not able to get those values in Mao which i created in this class, but i am getting values for "Company".
Help me with this?
Im the past, I added getter/setter for MAP type and it was work.
Did you try it? (getter/setter for 'values')
I'm not really sure what marshalling framework Spring uses behind the scenes and how it configures it (you could probably find out with some debugging and maybe make it work for your case), but you could always add an extra layer to your application and configure your own.
For instance you could use Jackson with yaml dataformat - https://dzone.com/articles/read-yaml-in-java-with-jackson.

Populating a HashMap with entries from a properties file for #Value

I have properties file which has a key company.id like this
company.id=key1=value1,key2=value2,key3=value4
Now, I want to store key-value pair directly in map using #Value of spring
//For example,
//for key in properties file
//company.list=comp1,comp2
#Value("#{'${proposal.provience}'.split(',')}")
List<String> companyList;
the above will directly converts to List.
Please tell me what to write here without using other libraries like Guava
#value(some logic here)
HashMap<String,String> map;

Categories

Resources