Properties setting via Servlet

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";

Answers


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.


Need Your Help

Changing a files metadata in Python

python metadata

Ok, I've searched around here but haven't found anything pointing to a solid answer.