4

I need to access the resource files in my web project from a class. The problem is that the paths of my development environment are different from the ones when the project is deployed.

For example, if I want to access some css files while developing I can do like this:

File file = new File("src/main/webapp/resources/styles/some.css/");

But this may not work once it's deployed because there's no src or main directories in the target folder. How could I access the files consistently?

Sanghyun Lee
  • 21,644
  • 19
  • 100
  • 126

5 Answers5

5

You seem to be storing your CSS file in the classpath for some unobvious reason. The folder name src is typical as default name of Eclipse's project source folder. And that it apparently magically works as being a relative path in the File constructor (bad, bad), only confirms that you're running this in the IDE context.

This is indeed not portable.

You should not be using File's constructor. If the resource is in the classpath, you need to get it as resource from the classpath.

InputStream input = getClass().getResourceAsStream("/main/webapp/resources/styles/some.css");
// ...

Assuming that the current class is running in the same context, this will work regardless of the runtime environment.

See also:


Update: ah, the functional requirement is now more clear.

Actually I want to get lastModified from the file. Is it possible with InputStream? –

Use getResource() instead to obtain it as an URL. Then you can open the connection on it and request for the lastModified.

URL url = getClass().getResource("/main/webapp/resources/styles/some.css");
long lastModified = url.openConnection().getLastModified();
// ...
Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Actually I want to get `lastModified` from the file. Is it possible with `InputStream`? – Sanghyun Lee Aug 01 '11 at 02:49
  • No, but it's possible with `URL`. – BalusC Aug 01 '11 at 02:53
  • That's great answer, but I have one more problem. I need to use `static` function to call it from JSTL. But `getClass` function can not be called inside static function. How can I resolve it? – Sanghyun Lee Aug 01 '11 at 04:06
  • 2
    Use the classloader of the current thread's context. `URL url = Thread.currentThread().getContextClassLoader().getResource(path);`. – BalusC Aug 01 '11 at 04:20
5

If what you're looking to do is open a file that's within the browser-visible part of the application, I'd suggest using ServletContext.getRealPath(...)

Thus:

File f = new File(this.getServletContext().getRealPath("relative/path/to/your/file"));

Note: if you're not within a servlet, you may have to jump through some additional hoops to get the ServletContext, but it should always be available to you in a web environment. This solution also allows you to put the .css file where the user's browser can see it, whereas putting it under /WEB-INF/ would hide the file from the user.

Ian McLaird
  • 5,507
  • 2
  • 22
  • 31
  • @lan if i am in other class(module class) except servlet how can i get access of my folder which is in my classpath of project... – Aniket Aug 06 '13 at 14:38
  • I think it would be better if you asked that as a new question, rather than trying to jump off from here. That will give you a chance to describe what you're trying to do better, and give others a chance to give you more detailed answers. – Ian McLaird Aug 06 '13 at 14:45
1

Put your external resources in a sub-directory of your project's WEB-INF folder. E.g., put your css resources in WEB-INF/styles and you should be able to access them as:

new File("styles/some.css");

Unless you're not using a standard WAR for deployment, in which case, you should explain your setup.

ig0774
  • 39,669
  • 3
  • 55
  • 57
  • Putting external resources in a sub-directory of `WEB-INF` folder is the best practice? @Robin said, "Typically resource files are placed in your war along with your class files". I'm confused – Sanghyun Lee Aug 01 '11 at 02:27
  • And it seems I cannot access the file like `new File("styles/some.css");` while developing. :( – Sanghyun Lee Aug 01 '11 at 02:34
1

Typically resource files are placed in your war along with your class files. Thus they will be on the classpath and can be looked up via

getClass.getResource("/resources/styles/some.css")

or by opening a File as @ig0774 mentioned.

If the resource is in a directory that is not deployed in the WAR (say you need to change it without redeploying), then you can use a VM arg to define the path to your resource.

-Dresource.dir=/src/main/webapp/resources

and do a lookup via that variable to load it.

Robin
  • 24,062
  • 5
  • 49
  • 58
0

In Java web project, the standard directory like:

{WEB-ROOT} / 
           /WEB-INF/
           /WEB-INF/lib/
           /WEB-INF/classes

So, if you can get the class files path in file system dynamic, you can get the resources file path.

you can get the path ( /WEB-INF/classes/ ) by:

this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath()

so, then the next ...

gelosie
  • 413
  • 1
  • 3
  • 11