How to Load a Resource from Web-Inf Directory of a Web Archive

How to load a resource from WEB-INF directory of a web archive

Use the getResourceAsStream() method on the ServletContext object, e.g.

servletContext.getResourceAsStream("/WEB-INF/myfile");

How you get a reference to the ServletContext depends on your application... do you want to do it from a Servlet or from a JSP?

EDITED: If you're inside a Servlet object, then call getServletContext(). If you're in JSP, use the predefined variable application.

How to load files/properties from WEB-INF directory?

The root of the classpath is the way to go.
Put your file in src/main/resources/auth.properties then set your resourcePath using
realm.setResourcePath("classpath:auth.properties");

Check the ExtendedPropertiesRealm and the tapestry-security testapp for an example

  • http://svn.codehaus.org/tynamo/trunk/tapestry-security/src/test/java/org/tynamo/security/testapp/services/AppModule.java

  • http://svn.codehaus.org/tynamo/trunk/tapestry-security/src/test/resources/shiro-users.properties

How do I reference a file that is placed in the WEB-INF folder when using Arquillian?

Option A) Use ServletContext.getResourceXXX()

You should have a Aquillarian MockHttpSession and a MockServletContext. E.g.:

@Test
public void myTest()
{
HttpSession session = new MockHttpSession(new MockServletContext());
ServletLifecycle.beginSession(session);

..testCode..

// You can obtain a ServletContext (will actually be a MockServletContext
// implementation):
ServletContext sc = session.getServletContext();
URL url = sc.getResource("/WEB-INF/testdata.xml")
Path resPath = new Path(url);
File resFile = new File(url);
FileReader resRdr = new FileReader(resFile);
etc...

..testCode..

ServletLifecycle.endSession(session);
}

You can create resource files & subdirectories in:

  1. the web module document root - resources are accessible from the browser and from classes
  2. WEB-INF/classes/ - resources are accessible to classes
  3. WEB-INF/lib/*.jar source jar - accessible to classes
  4. WEB-INF/lib/*.jar dedicated resource-only jar - accessible to classes
  5. WEB-INF/ directly within directory - accessible to classes. This is what you are asking for.

In all cases the resource can be accessed via:

URL url = sc.getResource("/<path from web doc root>/<resourceFileName>");
OR
InputStream resIS = sc.getResourceAsStream("/<path from web doc root>/<resourceFileName>");

>

These will be packaged into the WAR file and may be exploded into directories on the deployed app server OR they may stay within the WAR file on the app server. Either way - same behaviour for accessing resources: use ServletContext.getResourceXXX().

Note that as a general principle, (5) the top-level WEB-INF directory itself is intended for use by the server. It is 'polite' not to put your web resources directly in here or create your own directory directly in here. Instead, better to use (2) above.

JEE5 tutorial web modules
JEE6 tutorial web modules

Option B): Use Class.getResourceXXX()

First move the resource out of WEB-INF folder into WEB-INF/classes (or inside a jar WEB-INF/lib/*.jar).

If your test class is:

  • com.abc.pkg.test.MyTest in file WEB-INF/classes/com/abc/pkg/test/MyTest.class

And your resource file is

  • WEB-INF/classes/com/abc/pkg/test/resources/testdata.xml (or equivalent in a jar file)

Access File using Relative File Location, via the Java ClassLoader - finds Folders/Jars relative to Classpath:

java.net.URL resFileURL = MyTest.class.getResource("resources/testdata.xml");
File resFile = new File(fileURL);
OR
InputStream resFileIS =
MyTedy.class.getResourceAsStream("resources/testdata.xml");

Access File Using full Package-like Qualification, Using the Java ClassLoader - finds Folders/Jars relative to Classpath:

java.net.URL resFileURL = MyTest.class.getResource("/com/abc/pkg/test/resources/testdata.xml");
File resFile = new File(fileURL);
OR
InputStream resFileIS =
MyTest.class.getResourceAsStream("/com/abc/pkg/test/resources/testdata.xml");
OR
java.net.URL resFileURL = MyTest.class.getClassLoader().getResource("com/abc/pkg/test/resources/testdata.xml");
File resFile = new File(fileURL);
OR
InputStream resFileIS =
MyTest.class.getClassLoader().getResourceAsStream("com/abc/pkg/test/resources/testdata.xml");

Hope that nails it! @B)

File path to resource in our war/WEB-INF folder?

There's a couple ways of doing this. As long as the WAR file is expanded (a set of files instead of one .war file), you can use this API:

ServletContext context = getContext();
String fullPath = context.getRealPath("/WEB-INF/test/foo.txt");

http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/ServletContext.html#getRealPath(java.lang.String)

That will get you the full system path to the resource you are looking for. However, that won't work if the Servlet Container never expands the WAR file (like Tomcat). What will work is using the ServletContext's getResource methods.

ServletContext context = getContext();
URL resourceUrl = context.getResource("/WEB-INF/test/foo.txt");

or alternatively if you just want the input stream:

InputStream resourceContent = context.getResourceAsStream("/WEB-INF/test/foo.txt");

http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/ServletContext.html#getResource(java.lang.String)

The latter approach will work no matter what Servlet Container you use and where the application is installed. The former approach will only work if the WAR file is unzipped before deployment.

EDIT:
The getContext() method is obviously something you would have to implement. JSP pages make it available as the context field. In a servlet you get it from your ServletConfig which is passed into the servlet's init() method. If you store it at that time, you can get your ServletContext any time you want after that.

Java WebApp: Loading resource from .jar located in WEB-INF

You should use <name-of-known-class>.getResourseAsStream(?), which loads resources using the "local" classloader. In the case of a webapp, this will use the webapp's classloader.

The getServletContext().getResourceAsStream(?) method will return webapp resources relative to the webapp root, and cannot look inside JAR files.

The javadoc for this method describes the path you need to specify, but essentially you can use paths relative to the known class, e.g.

SomeKnownClass.class.getResourceAsStream("required-file.xml");


Related Topics



Leave a reply



Submit