How to get spring boot property file value as Map<String,String> - spring

In my project am having a requirement to retrieve a property file values in a map. This is how i wrote a code to retrieve property file value in a map. But values is not binding in the map. How can i achieve this.Is anything i missed?
specialist.properties
#Configuration
#ConfigurationProperties(prefix = "specialist")
#PropertySource("classpath:specialist.properties")
public class SpecialistProperties {
private Map<String,String> specialist=new HashMap<String,String>();
public Map<String, String> getSpecialist() {
return specialist;
}
public void setSpecialist(Map<String, String> specialist) {
this.specialist = specialist;
}
}
Controller class:
#RestController
public class MyappController {
#Autowired
private SpecialistProperties specialistProperties;
#GetMapping(value="/specialist")
public Map<String,String> getSpecialist()
{
return specialistProperties.getMap();
}
}
specialist.properties
specialist.name=Sam
specialist.availableDay=Wednesday
specialist.availableTime=5PM

You can set properties as shown below.
Make a file with name: application.properties with following code:
example.hello=Hello
example.user=Abhimanyu
example.howru=How are you?
example.mapProperty.key1=MapValue1
example.mapProperty.key2=MapValue2
example.listProperty[0]=ListValue1
example.listProperty[1]=ListValue2
OR:
Make a file with name: application.yml with the following code
example:
hello: Hello
user: Abhimanyu
howru: How are you?
mapProperty:
key1: MapValue1
key2: MapValue2
listProperty:
ListValue1
ListValue2
And you can verify/format your yaml file online by visiting https://jsonformatter.org/yaml-validator
For your reference refer following the link: http://jcombat.com/spring/how-to-read-properties-using-spring-boot-configurationproperties

I made a mistake by adding the #ConfigurationProperties(prefix="specialist"). No need of prefix="specialist". Because the map property value i have added as specialist, so there is no need of specialist in the ConfigurationProperties prefix. After the change it was worked good.
#Configuration
#ConfigurationProperties
#PropertySource("classpath:specialist.properties")
public class SpecialistProperties {
private Map<String,String> prop=new HashMap<String,String>();
public Map<String, String> getProp() {
return prop;
}
public void setProp(Map<String, String> prop) {
this.prop = prop;
}
}

Related

Read multiple properties file in one go using Spring Boot?

I went through the link: How to pass a Map<String, String> with application.properties and other related links multiple times, but still its not working.
I'm using Spring Boot and Spring REST example. Link Question: How to by default execute the latest version of endpoint in Spring Boot REST?.
I've created mapping something like this and simply read the mapping
get.customers={GET: '/app-data/customers', VERSION: 'v1'}
post.customers={POST: '/app-data/customers', VERSION: 'v1'}
get.customers.custId={GET: '/app-data/customers/{custId}', VERSION: 'v2'}
Code:
private String resolveLastVersion() {
// read from configuration or something
return "2";
}
Code:
#Component
#ConfigurationProperties
#PropertySource("classpath:restendpoint.properties")
public class PriorityProcessor {
private final Map<String, String> priorityMap = new HashMap<>();
public Map<String, String> getPriority() {
return priorityMap;
}
}
Code:
I suggest the following implementation:
#ConfigurationProperties(prefix="request")
public class ConfigurationProps {
private List<Mapping> mapping;
public List<Mapping> getMapping() {
return mapping;
}
public void setMapping(List<Mapping> mapping) {
this.mapping = mapping;
}
}
Class Mapping will denote the information about the single mapping:
public class Mapping {
private String method;
private String url;
private String version;
public Mapping(String method, String url, String version) {
this.method = method;
this.url = url;
this.version = version;
}
public Mapping() {
}
// getters setters here
}
On the Configuration or spring boot application class (the one with main method):
#EnableConfigurationProperties(ConfigurationProps.class)
In the properties file put:
request.mapping[0].method=get
request.mapping[0].url=/customers
request.mapping[0].version=1
request.mapping[1].method=post
request.mapping[1].url=/students
request.mapping[1].version=2
In Filter (I assume you followed my suggestion from the linked question):
#Component
#Order(1)
public class LatestVersionFilter implements Filter {
private List<Mapping> mappings;
public LatestVersionFilter(ConfigurationProps props) {
this.mappings = props.getMapping();
}
}

Jasypt: How to decrypt property stored in Map<String, String>?

Collegues, could you help to decrypt password (it is a value in stmCredentials map) from properties file using jasypt.
I have next strings in my properties file:
creds.users={testLogin: 'ENC(w0H***pgsj)'}
user2.login = ENC(9j3fHz5c****cLRCVvLTQmr5)
user2.pass = ENC(w0HxpKq7V3Lf***g3zs/hpgsj)
I run the test in debug mode:
#RunWith(SpringRunner.class)
#SpringBootTest
#ActiveProfiles("dev")
#Slf4j
public class CredentialsTest {
#BeforeClass
public static void beforeClass(){
System.setProperty("jasypt.encryptor.password", "C*******L");
}
#Autowired
StmCredentials stmCredentials;
#Value("${user2.login}")
private String user2Login;
#Value("${user2.pass}")
private String user2Pass;
#Test
public void getCredspairs() {
HashMap<String, String> credspairs = stmCredentials.getCredspairs();
}
}
After run I have next values in variables:
credspairs:
key: "testLogin"
value:"ENC(w0HxpKq7V3LfEPsU5mbd0Vg3zs/hpgsj)" //it wasn't decrypt =(
and (attention!)
user2Login = testLogin //it was decrypt
user2Pass = K1212Zrde
It seems that something wrong in my properties file, in creds.users property. I tried to use "single quotes, double quotes", but it doesn't help.
StmCredentials bean looks like:
#Component
#EnableConfigurationProperties
public class StmCredentials {
#Value("#{${creds.users}}")
private HashMap<String, String> credspairs;
public HashMap<String, String> getCredspairs() {
return credspairs;
}
public void setCredspairs(HashMap<String, String> somedata) {
this.credspairs = somedata;
}
}
How to decrypt password stored in StmCredentials (value)?
Thank you for any advice.
Hope this helps:
I don't think Jasypt can detect and decrypt values from properties file in this manner (from the limited span of my knowledge). You can try putting this in application.yml file if you can. It should work there. Anyway, here's what we can do:
This actually isn't the solution but a possible workaround. We can create a class to decrypt the values ourselves if Jasypt automatically won't do it for us.
import org.jasypt.encryption.StringEncryptor;
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
public class MyStringEncryptor {
private StringEncryptor encryptor;
public MyStringEncryptor(String password) {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword(password);
config.setAlgorithm("PBEWITHMD5ANDDES");
config.setKeyObtentionIterations("1000");
config.setPoolSize("1");
config.setProviderName("SunJCE");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setStringOutputType("base64");
encryptor.setConfig(config);
this.encryptor = encryptor;
}
public String encrypt(String message) {
return encryptor.encrypt(message);
}
public String decrypt(String message) {
return encryptor.decrypt(message);
}
}
Now we can create an object of MyStringEncryptor class and use the method decrypt to decrypt our desired value.
MyStringEncryptor encryptor = new MyStringEncryptor("mysecretpass"); // You can pass the password from properties file using #Value
String decryptedValue = encryptor.decerypt(encrypted-message);

Best Approach to load application.yml in spring boot application

I am having Spring Boot application and having application.yml with different properties and loading as below.
#Configuration
#ConfigurationProperties(prefix="applicationprops")
public class ApplicationPropHolder {
private Map<String,String> mapProperty;
private List<String> myListProperty;
//Getters & Setters
}
My Service or Controller Class in which I get this properties like below.
#Service
public ApplicationServiceImpl {
#Autowired
private ApplicationPropHolder applicationPropHolder;
public String getExtServiceInfo(){
Map<String,String> mapProperty = applicationPropHolder.getMapProperty();
String userName = mapProperty.get("user.name");
List<String> listProp = applicationPropHolder.getMyListProperty();
}
}
My application.yml
spring:
profile: dev
applicationprops:
mapProperty:
user.name: devUser
myListProperty:
- DevTestData
---
spring:
profile: stagging
applicationprops:
mapProperty:
user.name: stageUser
myListProperty:
- StageTestData
My questions are
In my Service class i am defining a variable and assigning Propertymap for every method invocation.Is it right appoach?
Is there any other better way I can get these maps without assigning local variable.
There are three easy ways you can assign the values to instance variables in your bean class.
Use the #Value annotation as follows
#Value("${applicationprops.mapProperty.user\.name}")
private String userName;
Use the #PostConstruct annotation as follows
#PostConstruct
public void fetchPropertiesAndAssignToInstanceVariables() {
Map<String, String> mapProperties = applicationPropHolder.getMapProperty();
this.userName = mapProperties.get( "user.name" );
}
Use #Autowired on a setter as follows
#Autowired
public void setApplicationPropHolder(ApplicationPropHolder propHolder) {
this.userName = propHolder.getMapProperty().get( "user.name" );
}
There may be others, but I'd say these are the most common ways.
Hope, you are code is fine.
Just use the below
#Configuration
#ConfigurationProperties(prefix="applicationprops")
public class ApplicationPropHolder {
private Map<String,String> mapProperty;
private List<String> myListProperty;
public String getUserName(){
return mapProperty.get("user.name");
}
public String getUserName(final String key){
return mapProperty.get(key);
}
}
#Service
public ApplicationServiceImpl {
#Autowired
private ApplicationPropHolder applicationPropHolder;
public String getExtServiceInfo(){
final String userName = applicationPropHolder.getUserName();
final List<String> listProp = applicationPropHolder.getMyListProperty();
}
}

How can I load propeties in a Map with SpringBoot?

I try to initialize a Map in my SpringBoot application but I am doing something wrong.
My config.properties:
myFieldMap.10000.fieldName=MyFieldName
myFieldMap.10000.fieldName2=MyFieldName2
myFieldMap.10001.fieldName=MyFieldName
myFieldMap.10001.fieldName2=MyFieldName2
myFieldMap.10002.fieldName=MyFieldName
myFieldMap.10003.fieldName2=MyFieldName2
...
(Isn't it possible to use some kind of bracket notation like myFieldMap[10001].fieldName for maps (I saw it used for lists).
I tried with my MyConfig.class:
#PropertySource("classpath:config.properties")
#Component
public class MyConfig {
private java.util.Map<Integer, MyMapping> theMappingsMap = new HashMap<Integer, MyMapping>();
public Map<String, MyMapping> getTheMappingsMap() {
return theMappingsMap;
}
public void setTheMappingsMap(Map<String, MyMapping> theMappingsMap) {
this.theMappingsMap= theMappingsMap;
}
public class MyMapping {
private String fieldName;
private String fieldName2;
public String getFieldName() {
return fieldName;
}
public String getFieldName2() {
return fieldName2;
}
public void setFieldName(final String fieldName) {
this.fieldName = fieldName;
}
public void setFieldName2(final String fieldName) {
this.fieldName2 = fieldName;
}
}
}
How do I have to adapt my code to let SpringBoot initialize my configuration (Map) with the definitions in the config.properties file?
You are missing #ConfigurationProperties annotation. Try this
#PropertySource("classpath:config.properties")
#Configuration
#ConfigurationProperties
public class MyConfig {
private java.util.Map<String, MyMapping> myFieldMap = new HashMap<>();
....
}
Another issue with your code is, if you want to make MyMapping class as an inner class of MyConfig, then you need to declare it as static. Or else you can make it as a separate class.

Trying to use properties file in spring boot

I have a locations.properties file which looks like this:
location.endpoint=testadres,andertestadres
location.test=teststring
I'm trying to read this config file with following class:
#Configuration
#PropertySource("classpath:locations.properties")
public class LocationProperties {
#Value("#{'${location.endpoint}'.split(',')}")
private List<String> locations;
#Value("${location.test}")
private String test;
public String getTest() {
return this.test;
}
public List<String> getLocations() {
return this.locations;
}
//To resolve ${} in #Value
#Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
return new PropertySourcesPlaceholderConfigurer();
}
}
But whenever I try to get the strings with getLocations() or getTest() I get null?
Just add .properties or .yml file to your /resources folder. Example
# simple.yml
demo:
connection:
username: sample
sample: My text
and add POJO class
#Component
#ConfigurationProperties(
prefix = "demo.connection",
locations = "classpath:sample.yml"
)
public class SampleSettings {
private String sample;
private String username;
..Getters and Setters mandatory

Resources