views:

2069

answers:

3

I want to read a file from a java web application. I don't want to give the absolute path of the file. I just want to put the file in some directory of my web application.

Or

It can be placed along with .war file (packaged web application).

What relative path to give for the file. I tried ./filename.csv but it didn't work.

========

Updated

========

I will deliver a WAR file (packaged web application) to my client. This web application will read a file (lets say SuppliedFile.csv) which will be copied to the server by the client. So I need a mechanism (that will work irrespective of whether the application server will unpak the WAR or not) so that web application can read that file.

Note: I am not using the SuppliedFile.csv in a servlet... I am using it in a plain Java class...

+3  A: 

Do you really need to load it from a file? If you place it along your classes (in WEB-INF/classes) you can get an InputStream to it using the class loader:

InputStream csv = 
   SomeClassInTheSamePackage.class.getResourceAsStream("filename.csv");
Thilo
Is there any other way... like what we do in standalone applications E.g. File file = new File("./fileName.csv");
Yatendra Goel
That depends on the "current working directory" which you have no control over. Even so, it will not work unless the webapp has been unpacked.
Mark Renouf
+2  A: 

If you have a path for that file in the web server, you can get the real path in the server's file system using ServletContext.getRealPath(). Note that it is not guaranteed to work in every container (as a container is not required to unpack the WAR file and store the content in the file system - most do though). And I guess it won't work with files in /WEB-INF, as they don't have a virtual path.

The alternative would be to use ServletContext.getResource() which returns a URI. This URI may be a 'file:' URL, but there's no guarantee for that.

Tim Jansen
@Tim I will deliver a WAR file (packaged web application) to my client. This web application will read a file (lets say `SuppliedFile.csv`) which will be copied to the server by the client. So I need a mechanism (that will work irrespective of whether the application server will unpak the WAR or not) so that web application can read that file.... Your first solution (getRealPath()) fails if app server doesn't unpack WAR file ... I think your second solution won't work because I am not using the `SuppliedFile.csv` in a servlet... I am using it in a plain Java class...
Yatendra Goel
+2  A: 

You may be able to simply access a pre-arranged file path on the system. This is preferable since files added to the webapp directory might be lost or the webapp may not be unpacked depending on system configuration.

In our server, we define a system property set in the App Server's JVM which points to the "home directory" for our app's external data. Of course this requires modification of the App Server's configuration (-DAPP_HOME=... added to JVM_OPTS at startup), we do it mainly to ease testing of code run outside the context of an App Server.

You could just as easily retrieve a path from the servlet config:

<web-app>
<context-param>
    <param-name>MyAppHome</param-name>
    <param-value>/usr/share/myapp</param-value>
</context-param>
...
</web-app>

Then retrieve this path and use it as the base path to read the file supplied by the client.

public class MyAppConfig implements ServletContextListener {

    // NOTE: static references are not a great idea, shown here for simplicity
    static File appHome;
    static File customerDataFile;

    public void contextInitialized(ServletContextEvent e) {

        appHome = new File(e.getServletContext().getInitParameter("MyAppHome"));
        File customerDataFile = new File(appHome, "SuppliedFile.csv");
    }
}

class DataProcessor {
    public void processData() {
        File dataFile = MyAppConfig.customerDataFile;
        // ...
    }
}

As I mentioned the most likely problem you'll encounter is security restrictions. Nothing guarantees webapps can ready any files above their webapp root. But there are generally simple methods for granting exceptions for specific paths to specific webapps.

Regardless of the code in which you then need to access this file, since you are running within a web application you are guaranteed this is initialized first, and can stash it's value somewhere convenient for the rest of your code to refer to, as in my example or better yet, just simply pass the path as a paramete to the code which needs it.

Mark Renouf
+1: do not have the customer place files into (or otherwise edit) the webapp directory (or the war file).
Thilo