• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Relative path of an XML file?

 
Ranch Hand
Posts: 50
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I want to parse an XML file in a JSP application, but it doesn't work with relative filepaths.

Of course i tried the usual suspects like

but it didn't work :-(

I also copied the file directly to the server, but with no result.

My questions:
1. I use Eclipse. In which folder in the Eclipse project should the xml file be located?
2. In which folder on the Tomcat-server should the xml file be located?
3. Which would be the file path then?


 
Marshal
Posts: 28177
95
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Daniel Zuckermann wrote:I also copied the file directly to the server, but with no result.



This makes it sound like your first attempts were trying to access a file which wasn't even on the same machine as the application server.

So could you clarify your post to explain what you tried, and what you expected your relative URLs to be relative to?
 
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
ItDoesntWorkIsUseless

Why didn't it work? What path did you end up with? How was it different from what you expected?
 
Daniel Zuckermann
Ranch Hand
Posts: 50
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The absolute path that works is: "C:\\ECLIPSE_WORKSPACE\\TestApp\\xml\\data.xml ";

This path should be replaced by a relative path.

Then I extracted the absolute file path and received only a temporary Eclipse deployment folder:
C:\ECLIPSE_WORKSPACE\.metadata\.plugins\org.eclips e.wst.server.core\tmp0\wtpwebapps\TestApp\xml\data .xml

I think i must manually copy the file to some folder on the Tomcat-server, but I don't know if this approach is right.
 
Bear Bibeault
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Wait a minute -- are you saying that the file isn't even on the server? How is the web app supposed to read it if not?
 
Daniel Zuckermann
Ranch Hand
Posts: 50
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I don't know if xml files are automatically copied to the server or if I have to copy them manually to some directory on the server.

As far as I know, all files are first created in the Eclipse project folder. When the application is built and started, the files are copied to some directories on the Tomcat-server. Am I right so far?
 
Bear Bibeault
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
As usual, relying on an IDE to deploy makes things 10x more complicated than it needs to be.

There should be a way to make eclipse include the XML file as part of the war file for deployment. I don't know what it is -- I don't use eclipse.

Once the file is properly deployed, you can use ServletContext.getResourceAsStream() to get at it.
 
Bear Bibeault
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
P.S. You want to avoid getRealPath() as it will fail in some circumstances (war file is not expanded).
 
Daniel Zuckermann
Ranch Hand
Posts: 50
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok, then the file is accessed like this:

Subsequently, the input must be converted to a file, right?

Why makes an IDE deployment so much more difficult and how could it be done better?
 
Bear Bibeault
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Daniel Zuckermann wrote:Subsequently, the input must be converted to a file, right?


Huh? If you've got an input stream you can just read it. Why the need for any "conversion"?

Why makes an IDE deployment so much more difficult and how could it be done better?


A bazillion settings, and restrictions that make it hard to mimic the real world.

Personally, I use an IDE (IntelliJ IDE) as an intelligent editor, but use Ant for building for deployment, and run a standalone Tomcat instance. Your mileage may vary.
 
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Daniel, maybe this example will give you an idea: http://www.kodejava.org/examples/140.html

Also, you can find more examples with a search for reading a file from a servlet

For non-trivial web applications, I use the Spring Framework because it not only encourages me to write loosely-coupled, well-tested components, but it also provides a lot of the plumbing code that helps with things like reading files. I'm a lazy programmer and I always try to find a way to write as little code as possible myself. There's a lot of good open-source software out there and you can save a lot of time and effort if you know where to look.
 
Daniel Zuckermann
Ranch Hand
Posts: 50
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks, but I haven't yet understood how this works in detail.

My XML parser class uses a normal File object:


According to this http://docs.oracle.com/javase/1.4.2/docs/api/javax/xml/parsers/DocumentBuilder.html , I could directly pass an InputStream to the parser. In my case this would
be a FileInputStream, right?
 
Junilu Lacar
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
parse is overloaded to take a File so you can call it the way you are doing now. Your problem is that the file can't be found, right? You can use File.exists() to check if you have specified the correct path. The article I cited might give you clues as to what you need to pass for the path.
 
Saloon Keeper
Posts: 27752
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
getRealPath may return null. If the webapp was not deployed as an exploded WAR, there is no real path, because the resource whose real path you are requesting resides inside the WAR file, not as a distinct file in the filesystem with a distinct filesystem path. There are times when I really wonder what genius created getRealPath to begin with.

Even if you do have an exploded WAR, getRealPath is a bad choice. If the XML file is a constant, read-only resource that's an integral and permanent part of the WAR, you are better off using the request getResourceAsStream() method in most cases. If the XML file is variable and/or uploaded you should absolutely positively not store it in the WAR. First, because if the WAR is not exploded, the file write will fail. Secondly, because the WAR may be updated an unforseen times, causing the uploaded file(s) to be destroyed without notice. And finally, because it's not an operation that is blessed by the J2EE and JEE standards. Always upload to an external directory that's outside of both your WAR and outside of your webapp server.
 
Daniel Zuckermann
Ranch Hand
Posts: 50
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It works with request getResourceAsStream(), but do I have to call input.close() in the servlet's destroy() method or is it not so important to do that?

If I have an index.jsp that requests data from a servlet that parses the xml and generates the beans out of the xml data sets, but where should the xml be parsed? When the XML file is large enough, it could happen that a button is pressed, but the data isn't already there. In the jsp I could overwrite the jspInit() method, but I would like to avoid scriptlets.

My idea is to start the application with a servlet instead of an index.jsp. This servlet's init() method acquires all resources (xml parsing, bean object creation....) and then forwards the request to the index.jsp.
 
Tim Holloway
Saloon Keeper
Posts: 27752
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You should always close inputstreams as soon as you are done using them. Waiting for them to be garbage-collected or leaving them hanging open just wastes resources and may hold annoying file locks as well.

I would normally put the XML parsing in a JavaBean and (usually) store the parsed DOM in/as another JavaBean. Such beans may be referenced from JSPs, servlets, or subsidiaries of JSPs and servlets.

If the XML is global to all users, you can store it as an application-scope object. In that case you would probably parse the XML text in a ContextListener at application startup.
 
Daniel Zuckermann
Ranch Hand
Posts: 50
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In my case, the bean objects are read-only and the same for all users. I have one singleton class that manages and stores the beans in a Vector. Upon request, a Vector element is copied and sent to the user.

How does it work with this ContextListener and where should it be called?

Right now, the application is started with an index.jsp. It contains some buttons to request the data. However, I am not sure if the index.jsp should be the starter page. The index.jsp directly communicates with the Controller. The Controller calls the singleton class and processes the requests (according to model2). Problem here: The Controller is first called when a button is clicked.


 
Tim Holloway
Saloon Keeper
Posts: 27752
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Actually, the webapp is started when the server deploys it, which can be when you explicitly deploy, or at server startup if the application had been deployed previously. If you instantiate a ServletContextListener and specify it in the WEB-INF/web.xml file, the "start" method can then kick off the process of parsing and holding your XML data. I do not recommend using a singleton class, however. Just keep the data in session scope.

Just as a side note, if the ultimate intent is to provide XML output using this XML as a model, a simpler solution might be to use the XML directly as a jspx. If the XML is serving in a more complex capacity (such as a Jasper Reports template or FO PDF template), you might want to consider an XML-friendly framework such as Apache Cocoon.
 
Daniel Zuckermann
Ranch Hand
Posts: 50
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I've overwritten the contextInitialized() method, but the problem here is, that I don't have a ServletContext to get the XMl file and save it as InputStream.

Maybe have to subclass HttpServlet and implement the ServletContextListener in the same class like

?
 
Tim Holloway
Saloon Keeper
Posts: 27752
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The ServletContext is in the ServletContextEvent that gets passed to the ServletContextListener contextInitialized and contextDestroyed methods.
 
Daniel Zuckermann
Ranch Hand
Posts: 50
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks, that works :-) In the contextDestroyed() method I've closed the InputStream.

It would also be nice to display some kind of "splash screen" or at least a "please wait..." message while the ServletContextListener is doing his work. Is this possible?
 
Tim Holloway
Saloon Keeper
Posts: 27752
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm very puzzled. Normally, I'd code a contextInitialized method that obtained the XML, parsed it into a DOM object, then stored that DOM object (Document) as an application-scope property, closing the inputstream immediately after parsing it. On no account would I leave it hanging open wasting resources until the contextDestroyed method was invoked at webapp shutdown.

No, you cannot display a splash screen. No HTTP server can produce output unless a client has made an explicit request for output via an HTTP request and even then the only allowable output is an HTTP Response outputstream, one - and only one - per request. Also, the contextInitialized method will be invoked before the webapp beings accepting requests. And finally, the output response is not an asynchronous data stream, so by the time a "splash screen" was accepted and displayable by a client, the waiting would already be over.
 
if you think brussel sprouts are yummy, you should try any other food. And this tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic