I want to load a certain number of properties files into the same java.util.Properties object. I achieve this correctly with the following code:
public class GloalPropReader {
public static final Properties DISPATCHER = new Properties();
public static final Properties GLOBAL_PROP = new Properties();
public GloalPropReader() {
try (InputStream input = GloalPropReader.class.getClassLoader().getResourceAsStream("dispatcher.properties")) {
DISPATCHER.load(input);
} catch (IOException ex) {
throw new RuntimeException("Can't access dispatcher information");
}
for (Object nth : DISPATCHER.keySet()) {
String nthKey = (String) nth;
String nthPathToOtherProps = (String) DISPATCHER.get(nthKey);
Path p = Paths.get(nthPathToOtherProps);
try (InputStream input = new FileInputStream(p.toFile())) {
GLOBAL_PROP.load(input);
} catch (IOException ex) {
throw new RuntimeException("Can't access " + nthPathToOtherProps + " information");
}
}
}
}
And having this properties files:
dispatcher.properties
path_to_prop_1=C:/Users/U/Desktop/k.properties
path_to_prop_2=C:/Users/U/Desktop/y.properties
k.properties
prop1=BLABLA
y.properties
prop2=BLEBLE
But what i would like to achieve is to throw a RuntimeException if 2 properties file have the same key inside. For instance, i would like this class to throw an exception if k.properties and y.properties were so:
k.properties
prop1=BLABLA
y.properties
prop1=BLEBLE
EDIT
It's the same as this post Loading multiple properties files but i don't want the overriding logic when 2 keys are equal
public static class GloalPropReader {
private final Properties K_PROPERTIES = new Properties();
private final Properties Y_PROPERTIES = new Properties();
public GloalPropReader() {
loadProperties("k.properties", K_PROPERTIES);
loadProperties("y.properties", Y_PROPERTIES);
Set intersection = new HashSet(K_PROPERTIES.keySet());
intersection.retainAll(Y_PROPERTIES.keySet());
if (!intersection.isEmpty()) {
throw new IllegalStateException("Property intersection detected " + intersection);
}
}
private void loadProperties(String name, Properties y_properties) {
try (InputStream input = GloalPropReader.class.getClassLoader().getResourceAsStream(name)) {
y_properties.load(input);
} catch (IOException ex) {
throw new RuntimeException("Can't access dispatcher information");
}
}
}
Related
I want to create a class that wraps Properties and specifically hides the file I/O operations. I have come up with the abridged code below. This is intended to read the properties from a file at a fixed location outside of the class path. It also has a method to write the properties to the same file.
//
/* Defines key properties of the iFlag application.
* Methods read and write properties.
*/
public class ClientProperties {
private Properties props;
private static String xPanelSizeStg = "32";
private static int xPanelSize = 32;
private static String configFilename = "/home/myname/config/client_config.properties";
public ClientProperties() {
props = new Properties();
}
/**
* Reads properties from file
* Reads the current properties object from file.
* The file is stored in /home/mimibox/config/flag_config.properties
*/
public Properties readPropertiesFromFile( ){
// create and load default properties
InputStream input = null;
logger.trace("Read flag config properties.");
try {
input = new FileInputStream( configFilename );
//load a properties file from class path, inside static method
props.load(input);
//get the property values and save
xPanelSizeStg = props.getProperty("xPanelsize","32");
yPanelSizeStg = props.getProperty("yPanelsize", "32");
}
catch (IOException ex) {
logger.error("Could not open config file" + configFilename,ex );
}
finally{
if(input!=null){
try {
input.close();
}
catch (IOException e) {
logger.error( "Could not close config file" + configFilename,e );
}
}
}
return props;
}
/**
* Writes properties to file
* Writes the current properties object to file.
* The file is stored in /home/mimibox/config/flag_config.properties
*/
public void writePropertiesToFile() {
//saves the current properties to file. Overwrites the existing properties.
Properties props = new Properties(); //a list of properties
OutputStream outStrm = null;
logger.info("Writing default flag config properties.");
System.out.println("Panel size x = " + xPanelSizeStg );
try {
outStrm = new FileOutputStream( configFilename );
// set the properties values
props.setProperty("xPanelsize", xPanelSizeStg);
props.setProperty("yPanelsize", yPanelSizeStg);
// save properties to file, include a header comment
props.store(outStrm, "This is the Server configuration file");
} catch (IOException io) {
logger.error( "The file :{0} could not be opened", configFilename,io);
} finally {
if (outStrm!= null) {
try {
outStrm.close();
} catch (IOException e) {
logger.error("The file :{0} could not be closed", configFilename, e);
}
}
}
}
}
The read and write methods work. What doesn't work is trying to change the value of a property, and then save it. The demo code below successfully reads the properties file and displays the correct value for XPanelsize.
I then change that value and attempt to write the properties to a file. The new value 64 for xPanelsize is not written to the file.
public static void main(String[] args) {
Properties props;
ClientProperties p = new ClientProperties();
props = p.readPropertiesFromFile();
String txt = props.getProperty("xPanelsize");
System.out.println("Panel size x = " + txt );
p.setProperty("xPanelsize","64"); //method not found error
p.writePropertiesToFile();
So I would like to be able to use the Property.setProperty() method to set the value of a property. When I do that, the changed property is not written to the file. I can see that is because I have more than 1 Property instance and one is not visible to the other. I think I need to extend the built-in Properties class to achieve what I want to do, but I am not sure how to make it all work.
I have found plenty of examples of using Properties on the internet. What I haven't found are any examples that hide the related file I/O in a class. How would I do that??
OK so thanks to the comments and answers above, I have made a number of changes. For the benefit of those that stumble upon this post, I have posted the working code in this answer. The main change is to extend Properties. This allows me to use the Properties methods directly.
package com.test;
import java.util.Properties;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.File;
public class ClientProperties extends Properties {
//initiate logger
private final static Logger logger = LogManager.getLogger();
private static String xPanelSizeStg = "32";
private static String yPanelSizeStg = "32";
private final configFilename = "/home/myname/myConfig.properties";
public ClientProperties() {
}
public Properties readPropertiesFromFile( ){
// create and load default properties
InputStream input = null;
logger.trace("Read flag config properties.");
try {
input = new FileInputStream( configFilename );
//load a properties file from class path, inside static method
this.load(input);
//get the property values and save
xPanelSizeStg = this.getProperty("xPanelsize","32");
yPanelSizeStg = this.getProperty("yPanelsize", "32");
}
catch (IOException ex) {
logger.error("Could not open config file" + configFilename,ex );
}
finally{
if(input!=null){
try {
input.close();
}
catch (IOException e) {
logger.error( "Could not close config file" + configFilename,e );
}
}
}
return this;
}
public void writePropertiesToFile() {
//saves the current properties to file. Overwrites the existing properties.
//Properties props = new Properties(); //a list of properties
OutputStream outStrm = null;
logger.info("Writing default flag config properties.");
System.out.println("Panel size x = " + xPanelSizeStg );
try {
outStrm = new FileOutputStream( configFilename );
// save properties to file, include a header comment
this.store(outStrm, "This is the Server configuration file");
} catch (IOException io) {
logger.error( "The file :{0} could not be opened", configFilename,io);
} finally {
if (outStrm!= null) {
try {
outStrm.close();
} catch (IOException e) {
logger.error("The file :{0} could not be closed", configFilename, e);
}
}
}
}
}
I have relied on the Properties parent to initiate Properties which I have accessed with "this". So now main looks like:
public static void main(String[] args) {
ClientProperties p = new ClientProperties();
p.readPropertiesFromFile();
String txt = p.getProperty("xPanelsize");
System.out.println("Panel size x = " + txt );
p.setProperty("xPanelsize","64");
p.writePropertiesToFile();
}
The class now hides all the admin around reading, writing and files. Crucially it avoids writing a setter/getter for each property (and I have a lot more properties than the two shown here). That is what I had in my first version.
Thanks for your help. It would have taken me a long time to figure all this out by myself.
You should probably need to create a getter for your 'props' object.
public Properties getProps()
{
return props;
}
And you will be able to invoke it like this:
p.getProps().setProperty("key", "value");
Or, if you are planning to make your ClientProperties class a children of Properties class, then you will need to use 'extends' and you would be able to invoke it by using
p.setProperty("key", "value");
And in this case you wouldn't need any Properties object in your class' fields.
This is my suggestion for your example.
First, you don't need to be edit again the properties in your writePropertiesToFile method like this:
public void writePropertiesToFile() {
// saves the current properties to file. Overwrites the existing properties.
// Properties props = new Properties(); // a list of properties
OutputStream outStrm = null;
logger.info("Writing default flag config properties.");
logger.debug("Panel size x = " + xPanelSizeStg);
try {
outStrm = new FileOutputStream(configFilename);
// set the properties values
//props.setProperty("xPanelsize", xPanelSizeStg);
//props.setProperty("yPanelsize", yPanelSizeStg);
// save properties to file, include a header comment
props.store(outStrm, "This is the Server configuration file");
} catch (IOException io) {
logger.error("The file :{0} could not be opened", configFilename, io);
} finally {
if (outStrm != null) {
try {
outStrm.close();
} catch (IOException e) {
logger.error("The file :{0} could not be closed", configFilename, e);
}
}
}
}
Then, you just create a setProperty method using the global variable -props- in the class.
private void setProperty(String key, String value) {
this.props.setProperty(key, value);
}
If your property file looks like image below:
The value of xPanelsize should be changed after running application.
public static void main(String[] args) {
Properties props = null;
ClientProperties p = new ClientProperties();
props = p.readPropertiesFromFile();
String xPanelsize = props.getProperty("xPanelsize");
System.out.println("Panel size x = " + xPanelsize);
p.setProperty("xPanelsize", "64"); // method not found error
p.writePropertiesToFile();
props = p.readPropertiesFromFile();
xPanelsize = props.getProperty("xPanelsize");
System.out.println("So, now the Panel size x = " + xPanelsize);
}
The debug message is,
The property file contents will be:
Here is full source:
package stackoverflow;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
import java.util.logging.Level;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/* Defines key properties of the iFlag application.
* Methods read and write properties.
*/
public class ClientProperties {
Logger logger = LoggerFactory.getLogger(ClientProperties.class.getSimpleName());
private Properties props;
private String xPanelSizeStg;
private String yPanelSizeStg;
private int xPanelSize;
private int yPanelSize;
// private static String configFilename =
// "/home/myname/config/client_config.properties";
private static String configFilename = "resource/client_config.properties";
public ClientProperties() {
props = new Properties();
xPanelSizeStg = "32";
yPanelSizeStg = "32";
xPanelSize = 32;
yPanelSize = 32;
}
/**
* Reads properties from file Reads the current properties object from file. The
* file is stored in /home/mimibox/config/flag_config.properties
*/
public Properties readPropertiesFromFile() {
// create and load default properties
InputStream input = null;
logger.trace("Read flag config properties.");
try {
input = new FileInputStream(configFilename);
// load a properties file from class path, inside static method
props.load(input);
// get the property values and save
xPanelSizeStg = props.getProperty("xPanelsize", "32");
yPanelSizeStg = props.getProperty("yPanelsize", "32");
} catch (IOException ex) {
logger.error("Could not open config file" + configFilename, ex);
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
logger.error("Could not close config file" + configFilename, e);
}
}
}
return props;
}
/**
* Writes properties to file Writes the current properties object to file. The
* file is stored in /home/mimibox/config/flag_config.properties
*/
public void writePropertiesToFile() {
// saves the current properties to file. Overwrites the existing properties.
// Properties props = new Properties(); // a list of properties
OutputStream outStrm = null;
logger.info("Writing default flag config properties.");
logger.debug("Panel size x = " + xPanelSizeStg);
try {
outStrm = new FileOutputStream(configFilename);
// set the properties values
//props.setProperty("xPanelsize", xPanelSizeStg);
//props.setProperty("yPanelsize", yPanelSizeStg);
// save properties to file, include a header comment
props.store(outStrm, "This is the Server configuration file");
} catch (IOException io) {
logger.error("The file :{0} could not be opened", configFilename, io);
} finally {
if (outStrm != null) {
try {
outStrm.close();
} catch (IOException e) {
logger.error("The file :{0} could not be closed", configFilename, e);
}
}
}
}
private void setProperty(String key, String value) {
this.props.setProperty(key, value);
}
public int getxPanelSize() {
return this.xPanelSize;
}
public void setxPanelSize(int xPanelSize) {
this.xPanelSize = xPanelSize;
}
public int getyPanelSize() {
return yPanelSize;
}
public void setyPanelSize(int yPanelSize) {
this.yPanelSize = yPanelSize;
}
public static void main(String[] args) {
Properties props = null;
ClientProperties p = new ClientProperties();
props = p.readPropertiesFromFile();
String xPanelsize = props.getProperty("xPanelsize");
System.out.println("Panel size x = " + xPanelsize);
p.setProperty("xPanelsize", "64"); // method not found error
p.writePropertiesToFile();
props = p.readPropertiesFromFile();
xPanelsize = props.getProperty("xPanelsize");
System.out.println("So, now the Panel size x = " + xPanelsize);
}
}
Hi I'm trying to make a PACS server using Java. dcm4che appears to be quite popular. But I'm unable to find any good examples about it.
As a starting point I inspected dcmqrscp and it successfully stores a DICOM image. But I cannot manage to handle a C-MOVE call. Here's my CMove handler. It finds requested the DICOM file adds a URL and other stuff, it doesn't throw any exception yet client doesn't receive any files.
private final class CMoveSCPImpl extends BasicCMoveSCP {
private final String[] qrLevels;
private final QueryRetrieveLevel rootLevel;
public CMoveSCPImpl(String sopClass, String... qrLevels) {
super(sopClass);
this.qrLevels = qrLevels;
this.rootLevel = QueryRetrieveLevel.valueOf(qrLevels[0]);
}
#Override
protected RetrieveTask calculateMatches(Association as, PresentationContext pc, final Attributes rq, Attributes keys) throws DicomServiceException {
QueryRetrieveLevel level = QueryRetrieveLevel.valueOf(keys, qrLevels);
try {
level.validateRetrieveKeys(keys, rootLevel, relational(as, rq));
} catch (Exception e) {
e.printStackTrace();
}
String moveDest = rq.getString(Tag.MoveDestination);
final Connection remote = new Connection("reciverAE",as.getSocket().getInetAddress().getHostAddress(), 11113);
if (remote == null)
throw new DicomServiceException(Status.MoveDestinationUnknown, "Move Destination: " + moveDest + " unknown");
List<T> matches = DcmQRSCP.this.calculateMatches(keys);
if (matches.isEmpty())
return null;
AAssociateRQ aarq;
Association storeas = null;
try {
aarq = makeAAssociateRQ(as.getLocalAET(), moveDest, matches);
storeas = openStoreAssociation(as, remote, aarq);
} catch (Exception e) {
e.printStackTrace();
}
BasicRetrieveTask<T> retrieveTask = null;
retrieveTask = new BasicRetrieveTask<T>(Dimse.C_MOVE_RQ, as, pc, rq, matches, storeas, new BasicCStoreSCU<T>());
retrieveTask.setSendPendingRSPInterval(getSendPendingCMoveInterval());
return retrieveTask;
}
private Association openStoreAssociation(Association as, Connection remote, AAssociateRQ aarq)
throws DicomServiceException {
try {
return as.getApplicationEntity().connect(as.getConnection(),
remote, aarq);
} catch (Exception e) {
throw new DicomServiceException(
Status.UnableToPerformSubOperations, e);
}
}
private AAssociateRQ makeAAssociateRQ(String callingAET,
String calledAET, List<T> matches) {
AAssociateRQ aarq = new AAssociateRQ();
aarq.setCalledAET(calledAET);
aarq.setCallingAET(callingAET);
for (InstanceLocator match : matches) {
if (aarq.addPresentationContextFor(match.cuid, match.tsuid)) {
if (!UID.ExplicitVRLittleEndian.equals(match.tsuid))
aarq.addPresentationContextFor(match.cuid,
UID.ExplicitVRLittleEndian);
if (!UID.ImplicitVRLittleEndian.equals(match.tsuid))
aarq.addPresentationContextFor(match.cuid,
UID.ImplicitVRLittleEndian);
}
}
return aarq;
}
private boolean relational(Association as, Attributes rq) {
String cuid = rq.getString(Tag.AffectedSOPClassUID);
ExtendedNegotiation extNeg = as.getAAssociateAC().getExtNegotiationFor(cuid);
return QueryOption.toOptions(extNeg).contains(
QueryOption.RELATIONAL);
}
}
I added the code below to send a DICOM file as a response:
String cuid = rq.getString(Tag.AffectedSOPClassUID);
String iuid = rq.getString(Tag.AffectedSOPInstanceUID);
String tsuid = pc.getTransferSyntax();
try {
DcmQRSCP.this.as=as;
File f = new File("D:\\dcmqrscpTestDCMDir\\1.2.840.113619.2.30.1.1762295590.1623.978668949.886\\1.2.840.113619.2.30.1.1762295590.1623.978668949.887\\1.2.840.113619.2.30.1.1762295590.1623.978668949.888");
FileInputStream in = new FileInputStream(f);
InputStreamDataWriter data = new InputStreamDataWriter(in);
// !1! as.cmove(cuid,1,keys,tsuid,"STORESCU");
as.cstore(cuid,iuid,1,data,tsuid,rspHandlerFactory.createDimseRSPHandler(f));
} catch (Exception e) {
e.printStackTrace();
}
Throws this exception
org.dcm4che3.net.NoRoleSelectionException: No Role Selection for SOP Class 1.2.840.10008.5.1.4.1.2.2.2 - Study Root Query/Retrieve Information Model - MOVE as SCU negotiated
You should add a role to the application instance like:
applicationEntity.addTransferCapability(
new TransferCapability(null, "*", TransferCapability.Role.SCP, "*"));
My application has different customers (around 20) , every customer has their own *.properties file with the connection settings, property parameters are the same.
Currently I have for every customer an own method to read the properties and store it in Customer. With 20 Customers, its inflated. I'm searching now for a better solution.
private final static Customer get_CustomerXXXX() {
final Properties p = new Properties();
p.load(S.class.getResourceAsStream("customerXXX.properties"));
return new Customer (p.getProperty("PARAM1", p.getProperty("PARAM2", p.getProperty("PARAM3")
}
if(SPECIFIC_CUSTOMER.XXXX) {
customerSettings = get_CustomerXXXX();
} else if(SPECIFIC_CUSTOMER.BBBB) {
customerSettings = get_CustomerBBBB();
}
property parameters are the same
if you are sure that in future also i'll be same. then you can read the property file first time only. From next time on wards, use values loaded from previous property file.
You can combine Singleton and Factory Method design patterns here.
You should have a method such as following:
private final static Properties getProperties(String idetifier)
{
Properties p = new Properties();
p.load(S.class.getResourceAsStream("customer"+idetifier+".properties"));
return p;
}
public class CustomerTest {
private String identifier;
public CustomerTest(String identifier) {
this.identifier = identifier;
}
public Properties getProerties() {
Properties p = null;
try {
p = new Properties();
p.load(CustomerTest.class.getResourceAsStream("customer" + identifier + ".properties"));
} catch (IOException e) {
e.printStackTrace();
}
return p;
}
}
this would be the way you suggested in the comments #OP.
I want to use a pre-configured properties File, load it, and after that, add a line under the already present line from the default config.properties.
I have a read() function that will read/load my default Properties file and I have a write() function that will add String key = "hey"; String value = "ho";
But when I launch read() and write() and when i look in the new config.properties I only see
hey=ho
In my default config.properties i got
ha=hi
hu=hu
But I want in my new config :
ha=hi
hu=hu
hey=ho
My code:
Properties prop = new Properties();
public static PropertiesIParse instance;
public PropertiesIParse() {
instance = this;
}
public PropertiesIParse getInstance() {
return instance;
}
public Properties getProp() {
return prop;
}
public void read() {
InputStream input = null;
try {
String filename = "/config.properties";
input = PropertiesIParse.class.getResourceAsStream(filename);
if (input == null) {
System.out.println("Sorry, unable to find " + filename);
return;
}
getProp().load(input);
Enumeration<?> e = getProp().propertyNames();
while (e.hasMoreElements()) {
String key = (String) e.nextElement();
String value = getProp().getProperty(key);
System.out.println("KeyKey : " + key + ", Value : " + value);
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void write() {
String filename = "config.properties";
FileOutputStream out;
//prop = new Properties();
String key = "hey";
String value = "ho";
try {
out = new FileOutputStream(filename, true);
getProp().setProperty(key, value);
getProp().store(out, "--type--"); // <---- variable pour dire YYYY MM DD etc.
out.close();
} catch (IOException i) {
System.out.println("Probleme avec l'écriture dans le fichier Property." + i.getMessage());
i.printStackTrace();
}
}
So, in my Main method:
new PropertiesIParse().getInstance().read();
new PropertiesIParse().getInstance().write();
EDIT
i change what you say but i got the same thing ... a new config.properties with only my prop.store(key,value) in it
Properties prop = new Properties();
static PropertiesIParse instance;
private PropertiesIParse() {
instance = this;
}
public static PropertiesIParse getInstance() {
if (instance== null) {
instance = new PropertiesIParse();
}
return instance;
}
public void read() {
InputStream input = null;
Properties prop = new Properties();
try {
String filename = "config.properties";
input = PropertiesIParse.class.getResourceAsStream(filename);
if (input == null) {
System.out.println("Sorry, unable to find " + filename);
return;
}
prop.load(input);
Enumeration<?> e = prop.propertyNames();
while (e.hasMoreElements()) {
String key = (String) e.nextElement();
String value =prop.getProperty(key);
System.out.println("Key : " + key + ", Value : " + value);
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void write(String key, String value) {
Properties prop = new Properties();
String filename = "./config.properties";
String comment="";
FileOutputStream out;
try {
out = new FileOutputStream(filename, true);
prop.setProperty(key, value);
prop.store(out, "-"+key+"-"+comment);
out.close();
} catch (IOException i) {
System.out.println("Probleme avec l'écriture dans le fichier Property." + i.getMessage());
i.printStackTrace();
}
}
My Main
PropertiesIParse.getInstance().read();
PropertiesIParse.getInstance().write(new String("ok"),new String("iiiii"));
And i only got ok=iiiii in it ... i surely miss something there, thanks for your help
Your singleton is broken as you use a public constructor. Each time you call -
new PropertiesIParse()
there a new instance of Properties will be created which will be empty.
Make the constructor private and change the getInstance() as follows
public PropertiesIParse getInstance() {
if (instance== null) {
instance = new PropertiesIParse();
}
return instance;
}
Then use it without using new:
PropertiesIParse.getInstance().read();
PropertiesIParse.getInstance().write();
I have got couple of Jersey REST Web services say SendPassword and ResetPassword whose purpose is to send email .
For sending email , i have configured a properties file under tomcat and all this works fine
The code of the SendPassword.java is somewhat this way
#Path("/sendpassword")
public class SendPassword {
#GET
#Produces("application/json")
public String sendPasswordToEmail(#QueryParam("empid") String empid)
throws JSONException
{
try {
SendEmailUtility.sendmail("weqw","2312");
}
catch(Exception e)
{
}
}
SendEmailUtility.java
public class SendEmailUtility
{
public static String sendmail(String sendemalto,String generatedpwd) throws IOException {
String result = "fail";
File configDir = new File(System.getProperty("catalina.base"), "conf");
File configFile = new File(configDir, "email.properties");
InputStream stream = new FileInputStream(configFile);
Properties props_load = new Properties();
props_load.load(stream);
final String username = props_load.getProperty("username");
final String password = props_load.getProperty("password");
Properties props_send = new Properties();
props_send.put("mail.smtp.auth","true");
props_send.put("mail.smtp.starttls.enable","true");
Transport.send(message);
// Some code to send email
result = "success";
} catch (MessagingException e) {
result = "fail";
e.printStackTrace();
}
return result;
}
}
As you can see i am reading the properties file for every call of the websercice
(As reading operation is somewhat costly) , Is there any way to resolve this ??
Could you please let me know whats the best approach to handle this.
Thanks in advance .
There are few ways to do this the one way of doing it is to make the props_load a private static member of the class and call it like this
public class SendEmailUtility
{
private static Properties props;
private static Properties getProperties() {
if (props == null) {
File configDir = new File(System.getProperty("catalina.base"), "conf");
File configFile = new File(configDir, "email.properties");
InputStream stream = new FileInputStream(configFile);
props = new Properties();
props.load(stream);
}
return props;
}
public static String sendmail(String sendemalto,String generatedpwd) throws IOException {
String result = "fail";
Properties props_load = getProperties();
final String username = props_load.getProperty("username");
final String password = props_load.getProperty("password");
Properties props_send = new Properties();
props_send.put("mail.smtp.auth","true");
props_send.put("mail.smtp.starttls.enable","true");
Transport.send(message);
// Some code to send email
result = "success";
} catch (MessagingException e) {
result = "fail";
e.printStackTrace();
}
return result;
}
}
The other design I would suggest is to make an email service class like EmailSender or EmailService and then inject it into SendPassword class
#Path("/sendpassword")
public class SendPassword {
#Autowired
EmailService emailService;
#GET
#Produces("application/json")
public String sendPasswordToEmail(#QueryParam("empid") String empid)
throws JSONException
{
I would recommend using resource bundle, which does not need InputStream
create a properties file and put directly inside your packages along with your java code
example folder structure
com
- preethi
-SendPassword.java
-email.properties
Then you can code like
ResourceBundle props_load = ResourceBundle.getBundle("com.preethi.email");
final String username = props_load.getString("username");
This way you don't have to worry about opening and closing the stream or file path
You could use a lazy-getter to fetch and cache the Properties object.
private static Properties props;
private static Properties getProperties() {
if (props == null) {
File configDir = new File(System.getProperty("catalina.base"), "conf");
File configFile = new File(configDir, "email.properties");
InputStream stream = new FileInputStream(configFile);
props = new Properties();
props.load(stream);
}
return props;
}
Each time you want to use the Properties, call getProperties(). It will cache it the first time it's called. Each subsequent call will just return the cached object.
Note: This example does not catch any exceptions.