Forums Register Login

Issue w/ accesing file from a Servlet

+Pie Number of slices to send: Send
Hello, I am trying to use a servlet to access a file called conf.xml. This is used to initialize the JPreference classes I am testing.

The servlet is using the servlet context's getRealPath() to find the location of the file: <web-app>/web/config/conf.xml. If it makes a differences, the web-app is running from a set of binaries configured as a context within the servlet container and not deployed as a war.

For some reason, it doesn't seem like the servlet is accessing the conf.xml. However, I am not gettting a FileNotFoundException either.

I am inlcluding my code at the bottom of this post. If this question is better suited for the Apache/Tomcat, Open Source Tools, or some other forum, please accept my apologies for posting here. I feel like it is a servlet issues having to do with accessing files, but maybe it is something specific to JPreferences or Tomcat.

Thanks!



The result is always "No name was supplied".
+Pie Number of slices to send: Send
I guess I'd start by issolating this statement...

webContext.getRealPath( "config\\conf.xml" )

...and sending the returned value to System.out to see what it was passing.

Based upon the error text it does not appear that statement is resolving the absolute addreess associated with the string you provided. Is it possible that the virtual path you provided does not exist in your app server?
+Pie Number of slices to send: Send
Thanks for the response. Here is the output for the real path:


When I add a BufferedReader to read and display the file contents, it is able to show me everything. When I try to access a value from the key defined in the XML for JPreferences, it acts like I can't. This may be a preferences BackingStore issue. Do you happen to know if I need to configure preferences differently for a web-context v. stand-alone. The code works in stand-alone app.
+Pie Number of slices to send: Send
The getRealPath function only works if you are running the app from an exploded file system.

Use ServletContext.getResourceAsStream if the file bundled with your webapp.
If not, configure the path as a servlet or context init-param and set it to a full absolute path.
+Pie Number of slices to send: Send
Also, you would never use a backslash "\" as a file delimiter with either getRealPath or with getResourceAsStream.

http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/ServletContext.html
+Pie Number of slices to send: Send
Ok, so are you saying that in using getRealPath(), I would always pass a string representing a single resource (e.g. "conf.xml instead of "config/conf.xml")? If that is the case, all of the resources would have to be stored in <<web-app>>/web, correct?

In the end, what I would like to acheive is a conf.xml file accessible only to the app and not the browser. I don't want clients hitting http://blah/conf.xml and seeing all of the preferences. So I may be setting this up wrong to begin with since I am storing it in my application under <<web-app>>/web/config.xml. Maybe it should be moved to WEB-INF somewhere.

Also, I don't want to retrieve the resource by making an external http request to get it either. I just want to point the location locally via an application relative path or absolute if there is no alternative.

If I use the getResourceAsStream() and create a new File() from the result, and then use that file to create my XmlStore(), I should be golden, right? That method will give me access from a servlet to any file in the app or server file system (assuming proper rights).

Am I getting warmer?
+Pie Number of slices to send: Send
 

Originally posted by M Kozelek:
Ok, so are you saying that in using getRealPath(), I would always pass a string representing a single resource (e.g. "conf.xml instead of "config/conf.xml")? If that is the case, all of the resources would have to be stored in <<web-app>>/web, correct?


Yes, a virtual path with '/' being the root of your webapp.


In the end, what I would like to acheive is a conf.xml file accessible only to the app and not the browser. I don't want clients hitting http://blah/conf.xml and seeing all of the preferences. So I may be setting this up wrong to begin with since I am storing it in my application under <<web-app>>/web/config.xml. Maybe it should be moved to WEB-INF somewhere.

Yes, I would put it under WEB-INF and access it with:
getServletContext().getResourceAsStream("/WEB-INF/myFile.xml");


Also, I don't want to retrieve the resource by making an external http request to get it either. I just want to point the location locally via an application relative path or absolute if there is no alternative.

You won't need to.


If I use the getResourceAsStream() and create a new File() from the result, and then use that file to create my XmlStore(), I should be golden, right? That method will give me access from a servlet to any file in the app or server file system (assuming proper rights).
Am I getting warmer?

getResourceAsStream is for files within your webapp.
You would need to use new File(..) for files on the file system that are not within your webapp.
+Pie Number of slices to send: Send
 

If I use the getResourceAsStream() and create a new File() from the result, and then use that file to create my XmlStore(), I should be golden, right? That method will give me access from a servlet to any file in the app or server file system (assuming proper rights).
Am I getting warmer?



You shouldn't need to go through the extra step of converting the stream to a file. Just parse the stream.

SimpleStream at http://simple.souther.us is an example that uses getResourceAsStream to access a file hidden behind WEB-INF
+Pie Number of slices to send: Send
I'm actually confused on your servlet. I'm not seeing how the image is streamed to the webpage unless that href is just inserting those bites as a image right then and there since it is a mapping to the servlet and the servlet just returns that stream. I like that approach, though. I'll have to mess around with that.

Please help bridge the gap here then. So I can get the file from behind WEB-INF as long as it is in bytes. However, I the JPreferences API creates the XML file store using the following methods:


Both of these are just string represenations of the path (which is the reason I was trying to use an real/absolute path).

So even if I get the buffered stream back, I'm not sure I can leverage it.

Feeling stuck...

http://my.unidata.ucar.edu/content/staff/caron/prefs/javadoc/index.html
+Pie Number of slices to send: Send
 

Originally posted by M Kozelek:
I'm actually confused on your servlet. I'm not seeing how the image is streamed to the webpage unless that href is just inserting those bites as a image right then and there since it is a mapping to the servlet and the servlet just returns that stream. I like that approach, though. I'll have to mess around with that.


That is what it's doing.


Please help bridge the gap here then. So I can get the file from behind WEB-INF as long as it is in bytes. However, I the JPreferences API creates the XML file store using the following methods:


Both of these are just string represenations of the path (which is the reason I was trying to use an real/absolute path).

So even if I get the buffered stream back, I'm not sure I can leverage it.

Feeling stuck...


That's all they give you?
Nothing that takes a stream?

You could write the file to the tempdir and read it from there.
It seems kind of lame that you can't pass a stream to that class.
Do you have a link to the API?


http://my.unidata.ucar.edu/content/staff/caron/prefs/javadoc/index.html[/QB]
I work in a unidata shop.
+Pie Number of slices to send: Send
Ahh, scratch that. It seems we are using an older library and I was totally ignoring the method description right there in the API online. I downloaded the source files and see that there is a way to create the Xml store from a stream. Testing it out now.

Jeepers...
[ May 11, 2005: Message edited by: M Kozelek ]
+Pie Number of slices to send: Send
Okay, I am still testing the inputstream, but it's still not working:

For the code:



This is the result:

+Pie Number of slices to send: Send
XMLStore userStore = XMLStore.createFromInputStream( in1, in2, null );

What is it looking for in that argument list?
+Pie Number of slices to send: Send
Here is the method implementation from the source file:

+Pie Number of slices to send: Send
Did you try it without reading the bytes from the beginning of th stream to do the println statments?



I don't fully understand why it wants two copies of the same stream.


(different Unidata (I was thinking about the IBM database)).
+Pie Number of slices to send: Send
No I haven't tried that. To be honest I don't event know how and would have to spend some time looking that up so I don't end up stuck there as well.

As far as why they need those two instances, here is the private implementation of the method:

+Pie Number of slices to send: Send
Looks like they DO want two copies of the same stream..

I meant something like this:
+Pie Number of slices to send: Send
Hi,

Its very simple to access a XML file from Servlet.

Use env entry in Web.xml and put the evn value and access the env entry using InitialContext Object

If you want code snippet let me know

Thanks
Bala L
+Pie Number of slices to send: Send
Thanks, Balasg. A code snippet would be great. It's been a while since I've worked with the servlet context stuff and I've been pulled away to focus on something else, but will have to resolve this at some point.

In the meantime, I will try to get back up to speed on how the container lets you leverage all the environment setup.

Thanks again!!!

mk
+Pie Number of slices to send: Send
Hi,

Add the following entry in Web.xml and restart the server

<env-entry id="EnvEntry_1">
<env-entry-name>ConfigFile</env-entry-name>
<env-entry-value>/export/home/bala/test.xml</env-entry-value>
<env-entry-type>java.lang.String</env-entry-type>
</env-entry>

and use the following code in ur servlet.

javax.naming.Context context = new javax.naming.InitialContext();
String initialConfigFile = (String) context.lookup ("java:comp/env/ConfigFile");

Thats it

Thanks
Bala L
+Pie Number of slices to send: Send
 

Originally posted by balasg jothi:
Hi,

Add the following entry in Web.xml and restart the server

<env-entry id="EnvEntry_1">
<env-entry-name>ConfigFile</env-entry-name>
<env-entry-value>/export/home/bala/test.xml</env-entry-value>
<env-entry-type>java.lang.String</env-entry-type>
</env-entry>

and use the following code in ur servlet.

javax.naming.Context context = new javax.naming.InitialContext();
String initialConfigFile = (String) context.lookup ("java:comp/env/ConfigFile");

Thats it

Thanks
Bala L



That just returns a string.
The issue at hand is how to read a an XML file that may or may not exist as
a file on the file system. In this case it's not. It's packed in a war file binary. That is what getResource and getResourceStream are designed to handle. They return the same results either way.
[ May 13, 2005: Message edited by: Ben Souther ]
+Pie Number of slices to send: Send
Actually, I may not have been as clear as I should have. The project is not deployed as a war. It is external to Tomcat and Tomcat is using the binaries from a context I set up in:

C:\Program Files\Apache Software Foundation\Tomcat 5.0\conf\Catalina\localhost\myapp.xml.

Don't know from a container perspective if that changes anything. The file is still stored in the WEB-INF/config/conf.xml.

The developer of the API I am using thinks the code looks right but wants me to make sure that the two inputstreams are non-null. Since I was using a reading line by line to the console, that tells me that it is not non-null, but maybe I misunderstand I/O.
+Pie Number of slices to send: Send
OK, I misunderstood. I thought you were running from a war file when you said from 'binaries'.

In that case you can just set the path to the xml file with either the env option as listed above or you can use simple servlet or context init-params.

I have examples of both at http://simple.souther.us

If you ever plan on running this from a packed war file, you would need to place the xml file somewhere outside of the web app to access it this way.
+Pie Number of slices to send: Send
So what is the difference between storing the path in the env-context and just giving it a hard-coded path.

I've tried hard coding it just to get there, but that doesn't return a stream either. The input stream is always null.

Does putting the path in the serlvet context somehow manipulate permissions to the file as well that normally wouldn't be there by just passing a path as a string? The end result of either approach is a String value representing the path anyway, right?

I can't believe how hard I'm making this.
+Pie Number of slices to send: Send
Is the xml file an actual file sittig on your hard drive?
Could you use that hard coded path to open it with a text editor?

Or..

Is it inside a war file?
+Pie Number of slices to send: Send
I am running this application off the binaries in a expoleded format external the tomcat program. In a totally other location on my local hard drive. The only relationship between my files and tomcat's is the context xml that points tomcat to my classes.

The conf.xml is a physical file located on my local file system. I am manipulating it in Netbeans, running tomcat from netbeans, and debugging from the IDE as well.

I have tried to access this physical file in every way I know how so at this point I'm at a loss. The debugger is now showing that the classes are not null, but they don't have any real state either. Just the default initial values.
+Pie Number of slices to send: Send
Ok, here is my latest attempt and the output. I'm using a FileInputStream because it doesn't return null like the InputStream alone does.



The result is the following:



Is there something here that I am missing? It seems I can get to the file and write it's content out, but I can't do anything else.
Are you here to take over the surface world? Because this tiny ad will stop you!
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com


reply
reply
This thread has been viewed 1754 times.
Similar Threads
object required in java script error
Preferences API
my servlet can't initialize: null
Cannot access a servlet from a Java application
Logging Problem with unpackWARs="false"
More...

All times above are in ranch (not your local) time.
The current ranch time is
Mar 29, 2024 09:23:52.