Properties setting via Servlet - java

I want to set data from configures.properties via servlet. configures.properties is locating in WEB-INF/classes. This is how I'm getting data:
public static String getDbPassword() {
Properties prop = new Properties();
try {
// load a properties file
InputStream in = Configures.class.getResourceAsStream(INPUT_FILE);
prop.load(in);
// get the property value
return prop.getProperty("dbPassword");
} catch (IOException ex) {
ex.printStackTrace();
}
return null;
}
But how to set? This is how I did:
public static void setDbPassword(String str) {
Properties prop = new Properties();
try {
//load a properties file
InputStream in = Configures.class.getResourceAsStream(INPUT_FILE);
prop.load(in);
prop.setProperty("dbPassword", str);
prop.store(new FileOutputStream(INPUT_FILE), null);
} catch (IOException ex) {
ex.printStackTrace();
}
}
But I'm catching java.io.FileNotFoundException after this. I think it happens after prop.store(new FileOutputStream(INPUT_FILE), null);. How should I modify OutputStream?
UPD:
This is how INPUT_FILE looks:
private static final String INPUT_FILE = "/config.properties";

Your INPUT_FILE is a resource path which getResourceAsStream will resolve relative to the classpath, but you're then trying to pass the same string to the FileOutputStream constructor which will try and treat it as an absolute path relative to the root of the filesystem. These are two different locations.
You could use ServletContext.getRealPath("WEB-INF/classes" + INPUT_FILE) to get the path you need for the FileOutputStream.
But the higher level issue here is that you shouldn't assume that your web application will have write access to its WEB-INF, or even that the directory exists on disk at all (e.g. if the app is running directly from a WAR rather than a directory unpacked on disk). If you want to store configuration data that can change then it should go in a file at a known location outside the web app (the location of this file could be an init parameter) where you know you will have read and write permission. This also stops your changes being overwritten when you deploy a new version of the app.

URL url = Configures.class.getResource(INPUT_FILE);
File file = new File(url.toURI());
OutputStream outputStream = new FileOutputStream(file);
...
prop.store(outputStream, null);

Try a FileWriter instead:
Writer writer = new FileWriter(INPUT_FILE);
...
prop.store(writer, null);

Can you try the following:
While reading the file
URL url = classLoader.getResource(INPUT_FILE);
InputStream in = url.openStream();
While writing :
new FileOutputStream(url.toURI().getPath())

Any files in your webapp should be considered read only. If you want mutable data you should use a database or some other data store.
J2EE advises against manipulating local files as it raises issues of clustering, transactions and security among other things.

Related

FileNotFoundException coming from Java web application

I am working on the web application with Eclipse. I have created one property file for database configuration. (DBProperty.properties)
Please find below screen-shot of the folder structure.
I want to access this property file. I am accessing with below code.
FileInputStream input = new FileInputStream("src/resources/DBProperty.properties");
I have also tried many relative paths but not able to succeed.
I have set build path for this project.
You need to use
MyClass.class.getClassLoader().getResourceAsStream("DBProperty.properties")
FileInputStream input = new FileInputStream("resources/DBProperty.properties");
Please try the above line of code. Hope it will solve your problem.
The src directory isn't there at runtime.
Resources are not files.
You need to look into Class.getResource() and friends.
You have to specify complete file path with File object.
public static void main(String[] args) {
File file = new File("C:\\Path\\workspace\\jbossmqimpl\\Test1\\resources\\NewFile.xml");
try (FileInputStream fis = new FileInputStream(file)) {
System.out.println("Total file size to read (in bytes) : "+ fis.available());
int content;
while ((content = fis.read()) != -1) {
// convert to char and display it
System.out.print((char) content);
}
} catch (IOException e) {
e.printStackTrace();
}
}

Updated property not shown in .properties using java

I am trying to store key and value pair in properties during server load. After saving, when i checked the .properties file, changes are not there. I am not sure what i missed out.
Not getting any exception or error. updated property changes is not reflected in my .properties file.
My resource file is in "src\main\resources\logintokencache.properties".
Properties prop = new Properties();
InputStream in = getClass().getClassLoader().getResourceAsStream("logintokencache.properties");
try {
prop.load(in);
prop.setProperty("key","value"); // Setting the property
// Tried using Filewriter to store the properties, not worked
File configFile = new File("logintokencache.properties");
FileWriter writer = new FileWriter(configFile);
prop.store(writer, null);
writer.close();
// Tried using FileOutputStream to store the properties, not worked
FileOutputStream output = new FileOutputStream("logintokencache.properties");
prop.store(output, "This is overwrite file");
// Reloaded the properties and also checked, not worked
prop.load(in);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
logintokencache.properties is stored at your working dir while the file you load is located somewhere at your classpath. So you are loading one file and store it to a different place.
If you are sure that the resource is writeable (that is not always be the case e.g. if it is insight a jar) you can access via
File f = new File(getClass().getClassLoader().getResource("logintokencache.properties").getFile());
FileOutputStream out = new FileOutputStream(f);
prop.store(out, "");

i want relative path for a file in java

I am new to java. I want to read a properties file in java. But i have my properties file in a different path in the same project.
I don't want to hard-code it. I want try with dynamic path.
Here is my code,
Properties properties = new Properties();
try{
File file = new File("myFile.properties");
FileInputStream fileInput = new FileInputStream(file);
properties.load(fileInput);
}catch(Exception ex)
{
System.err.println(ex.getMessage());
}
my file is in the folder, webapp/txt/myFile.properties.
Can any one help me in solving this issue?.
One way to solve this is split the absolute path to you file in two parts
Path till your project folder
path from you project folder onwards (Relative path)
You can tread these two properties in your application and concatenate and get the absolute path of the file. The relative path remains configurable.
public Properties loadDBProperties() {
InputStream dbPropInputStream = null;
dbPropInputStream = DbConnection.class
.getResourceAsStream("MyFile.properties");
dbProperties = new Properties();
try {
dbProperties.load(dbPropInputStream);
} catch (IOException ex) {
ex.printStackTrace();
}
return dbProperties;
}
you can call this method from
dbProperties = loadDBProperties();
String dbName = dbProperties.getProperty("db.schema");//you can read your line form here of properties file
if its under webapp/txt.myFile.properties and webapp is the public web space, then you need to read it using absolute URL
getServletContext().getRealpath("/txt/myFile.properties")
Properties prop=new Properties();
InputStream input = getServletContext().getResourceAsStream("/txt/myFile.properties");
prop.load(input);
System.out.println(prop.getProperty(<PROPERTY>));

Retrieve the web app root path in JSF Managed Bean

Im trying to access the example/web folder (see below in the image) in a jsf managed bean but cant seem to find a way to do it
thx
Try
FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath()
for build relative url's to resources in your app.
If you want the real path...
ServletContext ctx = (ServletContext) FacesContext.getCurrentInstance()
.getExternalContext().getContext();
String realPath = ctx.getRealPath("/");
If you want to get it as a File for some reason, then you need ExternalContext#getRealPath(). This converts a relative web path to an absolute disk file system. Since you need the web's root folder, just pass in /:
String absoluteWebPath = externalContext.getRealPath("/");
File webRoot = new File(absoluteWebPath);
// ...
Unrelated to the concrete problem, whatever functional requirement you've had in mind for which you thought that having an absolute local disk file system path to the web folder is the right solution, it has most definitely to be solved differently. And indeed, as per your comment on the other answer,
because Im trying to upload some file inside the folder and using the relative path
you're going the wrong path. You should not store uploaded files in there if you intend to keep them longer than the webapp's deployment lifetime. Whenever you redeploy the webapp (and on some server configs even when you restart the server), the uploaded files would get completely lost, simply because they are not contained as part of the original WAR file. Even more, some heavy server configs don't expand the WAR on disk at all, but in memory instead, the getRealPath() would then always return null.
Rather store it in a fixed disk file system path outside the server's deploy folder. Add that path in turn as a new server context or docroot, so that it's accessible on a different (virtual) context path. Or homegrow a servlet which gets an InputStream of it from disk and writes it to OutputStream of the response. See also this related answer: Uploaded image only available after refreshing the page
Try:
String relativePath="/resources/temp/";
String absolutePath= FacesContext.getCurrentInstance.getExternalContext().getRealPath(relativePath);
File file = new File(absolutePath);
to get real path.
Create a tmp file in resources/temp/ to avoid any exception.
Just wanted to thank Balus C. Code Java with JSP, in Tomcat/Tomee server I the following code that works:
private Boolean SaveUserItemImage(Part ui, String bid) throws IOException {
Boolean fileCreate = false;
OutputStream out = null;
InputStream filecontent = null;
ExternalContext ctx = context().getExternalContext();
String absoluteWebPath = ctx.getRealPath("/");
String resource_path = absoluteWebPath + "\\resources\\";
String image_path = resource_path + "\\" + this.itemType + "_images\\";
String buildFileName = image_path + bid + "_" + getFileName(ui);
File files = null;
try {
files = new File(buildFileName);
fileCreate = true;
} catch (Exception ex) {
System.out.println("Error in Creating New File");
Logger.getLogger(ItemBean.class.getName()).log(Level.SEVERE, null, ex);
}
if (fileCreate == true) {
if (files.exists()) {
/// User may be using same image file name but has been editted
files.delete();
}
try {
out = new FileOutputStream(files);
filecontent = ui.getInputStream();
int read = 0;
final byte[] bytes = new byte[1024];
while ((read = filecontent.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
fileCreate = true;
} catch (FileNotFoundException fne) {
fileCreate = false;
Logger.getLogger(ItemBean.class.getName()).log(Level.SEVERE, "SaveUserItemImage", fne);
} finally {
if (out != null) {
out.close();
}
if (filecontent != null) {
filecontent.close();
}
files = null;
}
}
return fileCreate;
}

Reading Properties file in Java

I have the following code trying to read a properties file:
Properties prop = new Properties();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream stream = loader.getResourceAsStream("myProp.properties");
prop.load(stream);
I get an exception at the last line. Specifically:
Exception in thread "main" java.lang.NullPointerException
at java.util.Properties$LineReader.readLine(Properties.java:418)
at java.util.Properties.load0(Properties.java:337)
at java.util.Properties.load(Properties.java:325)
at Assignment1.BaseStation.readPropertyFile(BaseStation.java:46)
at Assignment1.BaseStation.main(BaseStation.java:87)
thanks,
Nikos
Based on your exception, the InputStream is null, this means the class loader is not finding your properties file. I'm guessing that myProp.properties is in the root of your project, if that's the case, you need a preceding slash:
InputStream stream = loader.getResourceAsStream("/myProp.properties");
You can find information on this page:
http://www.mkyong.com/java/java-properties-file-examples/
Properties prop = new Properties();
try {
//load a properties file from class path, inside static method
prop.load(App.class.getClassLoader().getResourceAsStream("config.properties"));
//get the property value and print it out
System.out.println(prop.getProperty("database"));
System.out.println(prop.getProperty("dbuser"));
System.out.println(prop.getProperty("dbpassword"));
}
catch (IOException ex) {
ex.printStackTrace();
}
You can use ResourceBundle class to read the properties file.
ResourceBundle rb = ResourceBundle.getBundle("myProp.properties");
Properties prop = new Properties();
try {
prop.load(new FileInputStream("conf/filename.properties"));
} catch (IOException e) {
e.printStackTrace();
}
conf/filename.properties base on project root dir
You can't use this keyword like -
props.load(this.getClass().getResourceAsStream("myProps.properties"));
in a static context.
The best thing would be to get hold of application context like -
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:/META-INF/spring/app-context.xml");
then you can load the resource file from the classpath -
//load a properties file from class path, inside static method
prop.load(context.getClassLoader().getResourceAsStream("config.properties"));
This will work for both static and non static context and the best part is this properties file can be in any package/folder included in the application's classpath.
Your file should be available as com/example/foo/myProps.properties in classpath. Then load it as:
props.load(this.getClass().getResourceAsStream("myProps.properties"));
if your config.properties is not in src/main/resource directory and it is in root directory of the project then you need to do somethinglike below :-
Properties prop = new Properties();
File configFile = new File(myProp.properties);
InputStream stream = new FileInputStream(configFile);
prop.load(stream);
I see that the question is an old one. If anyone stumbles upon this in the future, I think this is one simple way of doing it.
Keep the properties file in your project folder.
FileReader reader = new FileReader("Config.properties");
Properties prop = new Properties();
prop.load(reader);
If your properties file path and your java class path are same then you should this.
For example:
src/myPackage/MyClass.java
src/myPackage/MyFile.properties
Properties prop = new Properties();
InputStream stream = MyClass.class.getResourceAsStream("MyFile.properties");
prop.load(stream);
Make sure that the file name is correct and that the file is actually in the class path. getResourceAsStream() will return null if this is not the case which causes the last line to throw the exception.
If myProp.properties is in the root directory of your project, use /myProp.properties instead.
You can use java.io.InputStream to read the file as shown below:
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(myProps.properties);
Given the context loader.getResourceAsStream("myPackage/myProp.properties") should be used.
Leading '/' doesn't work with ClassLoader.getResourceAsStream(String) method.
Alternatively you could use Class.getResourceAsStream(String) method, which uses '/' to determine if the path is absolute or relative to the class location.
Examples:
myClass.class.getResourceAsStream("myProp.properties")
myClass.class.getResourceAsStream("/myPackage/myProp.properties")
Many answers here describe dangerous methods where they instantiate a file input stream but do not get a reference to the input stream in order to close the stream later. This results in dangling input streams and memory leaks. The correct way of loading the properties should be similar to following:
Properties prop = new Properties();
try(InputStream fis = new FileInputStream("myProp.properties")) {
prop.load(fis);
}
catch(Exception e) {
System.out.println("Unable to find the specified properties file");
e.printStackTrace();
return;
}
Note the instantiating of the file input stream in try-with-resources block. Since a FileInputStream is autocloseable, it will be automatically closed after the try-with-resources block is exited. If you want to use a simple try block, you must explicitly close it using fis.close(); in the finally block.
None of the current answers show the InputStream being closed (this will leak a file descriptor), and/or don't deal with .getResourceAsStream() returning null when the resource is not found (this will lead to a NullPointerException with the confusing message, "inStream parameter is null"). You need something like the following:
String propertiesFilename = "server.properties";
Properties prop = new Properties();
try (var inputStream = getClass().getClassLoader().getResourceAsStream(propertiesFilename)) {
if (inputStream == null) {
throw new FileNotFoundException(propertiesFilename);
}
prop.load(inputStream);
} catch (IOException e) {
throw new RuntimeException(
"Could not read " + propertiesFilename + " resource file: " + e);
}
A good practice which is not state in previous solution is to passing properties especially the property files that generated in compile time with build plugins perhaps, is to Use PropertySourcesPlaceholderConfigurer
#Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
PropertySourcesPlaceholderConfigurer propsConfig
= new PropertySourcesPlaceholderConfigurer();
propsConfig.setLocation(new ClassPathResource("myProp.properties"));
propsConfig.setIgnoreResourceNotFound(true);
propsConfig.setIgnoreUnresolvablePlaceholders(true);
return propsConfig;
}
then can accessing the properties from IOC as demand such
#Value("${your.desired.property.pointer}")
private String value;
For Reading Properties file with its original order:
File file = new File("../config/edc.properties");
PropertiesConfiguration config = new PropertiesConfiguration();
PropertiesConfigurationLayout layout = new PropertiesConfigurationLayout(config);
layout.load(new InputStreamReader(new FileInputStream(file)));
for(Object propKey : layout.getKeys()){
PropertiesConfiguration propval = layout.getConfiguration();
String value = propval.getProperty((String) propKey).toString();
out.print("Current Key:" + propkey + "Current Value:" + propval + "<br>");
}
Specify the path starting from src as below:
src/main/resources/myprop.proper

Categories