I am load the properties file and get the value from that file but when i using "Properties" class and getProperty(key) method, it was return null value.
code:
public class LoadPropertiesFile {
public static String getProperty (String key, String filePath) {
Properties properties = new Properties();
InputStream inputStream = null;
String value = null;
try {
String appHome = ConfigUtil.getApplicationHome() + filePath;
inputStream = new FileInputStream(appHome);
//load a properties file
properties.load(inputStream);
//get the property value
System.out.println(properties.getProperty("7")); //print **Unlock**
System.err.println(key); //print **7**
System.out.println(value); //print **null**
value = properties.getProperty(key);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch(IOException e) {
e.printStackTrace();
}
}
}
return value;
}
}
Output:
Unlock
7
null
Property File:
2=Interactive
3=Network
4=Batch
5=Service
7=Unlock
8=Network Cleartext
10=Remote Desktop
11=Logon with cached credentials
call method:
logonType = new LoadPropertiesFile().getProperty("7", "path");
When i call that method it will return null value only. please help me guys.
You are initalizing value with null.
String value = null;
And you assign it after printing it:
System.out.println(value);
value = properties.getProperty(key);
Output: null
So value can only be null when you print it, as you never change its value until System.out.println(value);.
Just switch those two statements:
value = properties.getProperty(key);
System.out.println(value);
Output: unlock
Edit
properties.getProperty(key) may return null too, but only if there is no such key in its table, otherwise it will return the assigned value, in your example unlock.
See the API Documentation on this for more details:
public String getProperty(String key)
Searches for the property with the specified key in this property list. If the key is not found in
this property list, the default property list, and its defaults,
recursively, are then checked. The method returns null if the property
is not found.
http://docs.oracle.com/javase/7/docs/api/java/util/Properties.html#getProperty(java.lang.String)
System.out.println(value); //print **null**
value = properties.getProperty(key);
Switch these two lines and initialize value before printing it:
value = properties.getProperty(key);
System.out.println(value); //print Unlock
Related
I have spring boot application where the user sends parameter and based on this parameter, there are configuration should be get.
I created file name configuration type “Configration_Types.properies” , now how can I read the configuration based on parameter pass I don't want to create database to lookup it?
Type1=Type1
Type1.width=60
Type1.heght=715
Type2=Type2
Type2.width=100
Type2.heght=720
Type3=Type3
Type3.width=100
Type3.heght=700
Type4=Type4
Type4.width=450
Type4.heght=680
Type5=Type5
Type5.width=270
Type5.heght=750
for example pass type4 should get configuration
Type4
450
680
The function could be like that :
public void readPropertyByType(String type)
{
InputStream input = null;
try
{
Properties prop = new Properties();
// if your type is Type4, the typeKey will be Type4. for compare data
String typeKey = type + ".";
String filename = "config.properties";
input = new FileInputStream(filename);
prop.load(input);
String typeInformation = "";
Enumeration< ? > e = prop.propertyNames();
while (e.hasMoreElements())
{
String key = (String)e.nextElement();
if (key.indexOf(typeKey) > 0)
{
typeInformation = typeInformation + prop.getProperty(key);
}
}
System.out.println("The data of type " + type + "is :" + typeInformation);
}
catch (IOException ex)
{
ex.printStackTrace();
}
finally
{
if (input != null)
{
try
{
input.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
But you make a better design for your property file.
In case the order of property file never change, you can stop the
function when you get all expected data, don't need to loop whole
file.
Hope it help.
---UPDATE---
The property file could be like that :
Option 1
Type4.width=450
Type4.heght=680
Type5.width=450
Type5.heght=680
Option 2
Type4=450, 680
Type5=450, 680
Depend on each option, you can break the while loop when you got the expected data.
If you can modified your property file Configration_Types.properies like:-
type[0].width=60
type[0].heght=715
type[1].width=100
type[1].heght=720
type[2].width=100
type[2].heght=700
type[3].width=450
type[3].heght=680
type[4].width=270
type[4].heght=750
And your class for consume property values from property file would be:-
#Component
#ConfigurationProperties("type") // prefix type, find type.* values
public class GlobalProperties {
private List<Type> type = new ArrayList<Type>();
//getters and setters
public static class Type
{
private int width;
private int heght;
// getter setter
}
And As based on user params you can access the value from arraylist.
hope this help:
I have a below method which does URL decoding on the value passed along with using charset.
public String decodeValue(String value, Charset charset) {
if (!Strings.isNullOrEmpty(value)) {
try {
value = URLDecoder.decode(value, charset.name());
} catch (UnsupportedEncodingException ex) {
// log error
return null;
}
}
return value;
}
Now if URLDecoder.decode line throws UnsupportedEncodingException first time then I want to run same value against below three lines:
value = value.replaceAll("%(?![0-9a-fA-F]{2})", "%25");
value = value.replaceAll("\\+", "%2B");
value = URLDecoder.decode(value, charset.name());
And if then again URLDecoder.decode line throws exception second time, then I will log the error but only second time and return null value otherwise return the value which is decoded.
What is the best and elegant way to do this?
The easiest way is to make a private version of your function signature which includes an extra flag.
private String decodeValue(String value, Charset charset, boolean isFirstTime) {
if (!Strings.isNullOrEmpty(value)) {
try {
value = URLDecoder.decode(value, charset.name());
} catch (UnsupportedEncodingException ex) {
if (isFirstTime) {
value = value.replaceAll("%(?![0-9a-fA-F]{2})", "%25");
value = value.replaceAll("\\+", "%2B");
return decodeValue(value, charset.name(), false);
} else {
// log error
return null;
}
}
}
return value;
}
Then, just pass true the first time and false in the recursive call. Inside the function, only execute the next three lines if true is passed.
The public version can pass true.
public String decodeValue(String value, Charset charset) {
decodeValue(value, charset, true);
}
While it isn't recursive, you could make use of a while loop and a flag.
public String decode(String value, Charset charset) {
boolean first = true;
while(!Strings.isNullOrEmpty(value)) {
try {
return value = URLDecoder.decode(value, charset);
} catch (UnsupportedEncodingException e) {
if(first == false) {
// Log error.
return null;
}
value = value.replaceAll("%(?![0-9a-fA-F]{2})", "%25").replaceAll("\\+", "%2B");
}
first = false;
}
return value;
}
Here you go :
public String decode(String value, Charset charset) {
if (!Strings.isNullOrEmpty(value)) {
try {
value = URLDecoder.decode(value, charset.name());
} catch (UnsupportedEncodingException ex) {
try {
value = value.replaceAll("%(?![0-9a-fA-F]{2})", "%25");
value = value.replaceAll("\\+", "%2B");
value = URLDecoder.decode(value, charset.name());
} catch (UnsupportedEncodingException ex) {
// log error
return null;
}
}
}
return value;
}
Hope this solves your problem.
Adding a flag is one option. Yes, it is the easier one; but many people argue that having flags is simply spoken: bad practice.
You simply try to minimize those things.
In other words: if you have a method that should behave differently for the first and subsequent calls; consider creating two methods there. Of course, you avoid code duplication as far as possible, but unless it becomes to costly, you should at least consider avoiding such flag arguments, too.
Here is version without extra flags, duplicated code, recursion and loops:
public String decodeValue(final String value, Charset charset) throws UnsupportedEncodingException {
String result;
if (!Strings.isNullOrEmpty(value)) {
UnsupportedEncodingException[] lastException = new UnsupportedEncodingException[1];
result = Stream.<Function<String, String>>of(
Function.identity(),
s -> {
s = s.replaceAll("%(?![0-9a-fA-F]{2})", "%25");
s = s.replaceAll("\\+", "%2B");
return s;
})
.map(f -> f.apply(value))
.map(appliedValue -> {
try {
return URLDecoder.decode(appliedValue, charset.name());
} catch (UnsupportedEncodingException e) {
lastException[0] = e;
return null;
}
})
.filter(Objects::nonNull)
.findFirst()
.orElseThrow(() -> lastException[0]);
}
return result;
}
Here I just take stream with 2 functions: identity and function making string correction. Then I apply these functions to initial string and try to decode. If first attempt is successful then code will not apply correction function and just return correct result. If decoder throws exception after value correction then "findFirst" will not find any value. Then we throw last caught exception.
I have the following code which must add new values to the existing properties in the .properties file of, if the property doesn't exist - create it.
public String saveProperties(ArrayList<Property> properties, String customerId){
final String userPropFieldName = "users." + customerId + ".rules";
try{
PropertiesConfiguration props = new PropertiesConfiguration("/home/mikhail/bzrrep/DLP/DLPServer/src/main/resources/rules.properties");
for (Property property: properties){
String fieldName = "rules." + property.getName() + "." + property.getType();
String[] values = (property.getValue()).split("\\,");
for (String word: values){
System.out.print(word + " ");
}
if (util.exist(fieldName, props)){
props.setProperty(fieldName, values);
} else {
props.addProperty(fieldName, values);
}
String[] userProperties = props.getStringArray(userPropFieldName);
if (property.getAccepted()){
userProperties = util.addNewValue(userProperties, fieldName);
} else {
userProperties = util.removeValue(userProperties, fieldName);
}
props.setProperty(userPropFieldName, userProperties);
}
}catch (ConfigurationException e){
e.printStackTrace();
}
return "Saved";
}
I run it with the debugger and all values right, I mean, there are the proper name of the property and the proper values in the array, so, seen that it came up to the adding or setting new value, but finally I didn't see any changes in the property file.
Save your modified properties to file
props.save();
Read more: http://commons.apache.org/proper/commons-configuration/userguide/howto_properties.html#Saving
BTW, Saving properties directly to source code (src/main/resources/rules.properties) is usually bad idea.
I have a java code to append the values into my properties file
My properties file will have an entry like this.
key1 = host,port,orcl,username,password
key2 = host,port,orcl,username,password
key3 = host,port,orcl,username,password and so on...
these key1, key2 and key3 are connection names.
Before doing an entry into properties file, first i have to check whether the file has given connection name entry. i mean, if user again entering the value using key1 or key2 or key3 connection name, it has to give an alert saying that this connection name is available so try with another name.
Here is my java code to make an entry into file:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
try
{
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
con = DriverManager.getConnection("jdbc:oracle:thin:#"+host+":"+port+"/"+service,username,password);
con.setAutoCommit(false);
if (con!=null)
{
session.setAttribute(username, con);
out.println("Connected Successfully");
PrintWriter out1 = new PrintWriter(new BufferedWriter(new FileWriter("my properties file", true)));
out1.println(cname+" = "+host+","+port+","+service+","+username+","+password);
out1.close();
}
else
{
out.println("Error in getting connection");
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
Properties prop = new Properties();
prop.load("pathToPropertiesFile");
String key; //This is the key which user will enter
String propKey = prop.getProperty(key);
if(propKey == null)
{
// Key is not present so enter the key into the properties file
prop.setProperty("keyName", key);
}
else
{
// Throw error saying key already exists
out.println("Key "+key+" already exists.");
}
Refer Here for more information and example on Properties in Java
Updated:
Okay, if you wish to check whether such value is present (irrespective) of any key, then use this code
// Ignoring the loading of the properties file
// Assuming properties file is loaded in "prop"
Enumeration keySet = prop.keys();
String key; // This is the key which user will enter
boolean keyExists = false;
while(keySet.hasMoreElements())
{
String keyName = (String) keySet.nextElement();
String keyValue = prop.getProperty(keyName);
if( key.equals(keyValue)) //Check against all the keys' value present
{
keyExists = true;
break;
}
}
if(keyExists)
{
//throw error
}
else
{
//insert key
}
The approach is to get all the keys present and check against its values. If the value present in the properties file is same as that user entered or otherwise then you know what is to be done
If you want to make the check against the KeyName then just change the if condition in the loop
if( key.equals(keyName)) //Check against all the key Name present in the properties file
{
keyExists = true;
break;
}
Hope this helps!!
Look at the Properties class. It has some pertinent methods that may be of use;
load()
save()
setProperty()
containsKey()
I have a Java Properties object that I load from an in-memory String, that was previously loaded into memory from the actual .properties file like this:
this.propertyFilesCache.put(file, FileUtils.fileToString(propFile));
The util fileToString actually reads in the text from the file and the rest of the code stores it in a HashMap called propertyFilesCache. Later, I read the file text from the HashMap as a String and reload it into a Java Properties object like so:
String propFileStr = this.propertyFilesCache.get(fileName);
Properties tempProps = new Properties();
try {
tempProps.load(new ByteArrayInputStream(propFileStr.getBytes()));
} catch (Exception e) {
log.debug(e.getMessage());
}
tempProps.setProperty(prop, propVal);
At this point, I've replaced my property in my in-memory property file and I want to get the text from the Properties object as if I was reading a File object like I did up above. Is there a simple way to do this or am I going to have to iterate over the properties and create the String manually?
public static String getPropertyAsString(Properties prop) {
StringWriter writer = new StringWriter();
prop.list(new PrintWriter(writer));
return writer.getBuffer().toString();
}
There seems to be a problem with #Isiu answer. After that code Properties are truncated, like there is some limit to string length. Proper way is to use code like this:
public static String getPropertyAsString(Properties prop) {
StringWriter writer = new StringWriter();
try {
prop.store(writer, "");
} catch (IOException e) {
...
}
return writer.getBuffer().toString();
}
It's not directly related to your question but if you just want to print out properties for debugging you can do something like this
properties.list(System.out);
If you are using Java 8 or above, here is a single statement solution with the possibility to control the format by yourself:
String properties = System.getProperties().entrySet()
.stream()
.map(e -> e.getKey() + ":" + e.getValue())
.collect(Collectors.joining(", "));
I don't completely understand what you're trying to do, but you can use the Properties class' store(OutputStream out, String comments) method. From the javadoc:
public void store(OutputStream out,
String comments)
throws IOException
Writes this property list (key and element pairs) in this Properties table to the output stream in a format suitable for loading into a Properties table using the load(InputStream) method.
You can do as below also:
Properties p = System.getProperties();
Enumeration keys = p.keys();
while (keys.hasMoreElements()) {
String key = (String)keys.nextElement();
String value = (String)p.get(key);
System.out.println(key + ": " + value);
}
Another function to print all the values of a field is :
public static <T>void printFieldValue(T obj)
{
System.out.printf("###" + obj.getClass().getName() + "###");
for (java.lang.reflect.Field field : obj.getClass().getDeclaredFields()) {
field.setAccessible(true);
String name = field.getName();
Object value = null;
try{
value = field.get(obj);
}catch(Throwable e){}
System.out.printf("#Field name: %s\t=> %s%n", name, value);
}
}
Using the list method is incorrect because it should be used only for debugging purposes
Prints this property list out to the specified output stream.
This method is useful for debugging.
It doesn't escape keys which contains special characters, like = or :.
The store method should be used, but it inserts a comment and timestamp. The following code removes these additional lines and returns a text with normalized new lines.
Java
public static String propertiesToString(Properties properties) throws IOException {
if (properties == null) {
return null;
}
if (properties.isEmpty()) {
return "";
}
StringWriter writer = new StringWriter();
properties.store(writer, null);
String text = normalizeNewLines(writer.toString());
List<String> lines = new ArrayList<>(Arrays.asList(text.split("\n")));
lines.remove(0);
return lines.stream().collect(Collectors.joining("\n"));
}
private static String normalizeNewLines(String text) {
return text.replace("\r\n", "\n").replace("\r", "\n");
}
Groovy
static String propertiesToString(Properties properties) {
if (properties.is(null)) {
return null
}
if (properties.isEmpty()) {
return ''
}
def writer = new StringWriter()
properties.store(writer, null)
def lines = normalizeNewLines(writer).split('\n') as List
lines.remove(0)
return lines.join('\n')
}
private static String normalizeNewLines(String text) {
return text.replace('\r\n', '\n').replace('\r', '\n')
}