[jdom-interest] Re: Problems with JSP/JDOM
Per Norrman
per.norrman at austers.se
Thu Sep 23 05:20:26 PDT 2004
Flávio Marim wrote:
> Thanks lot. But my JSP doesn't involve file writing. It calls another app
> that works with sockets. The response XML comes over the socket and can
> never be stored as a file. It must be parsed and formatted as HTML using
> the socket OutputStream. Sometimes it works, sometimes I get "Premature
> end of file exception". No idea about this. I can't identify what's going
> wrong since the app behavior seems randomical.
>
> The JSP fragment where I believe the problem resides is:
>
> <%
>
> // at this point, inputDoc is correctly assembled.
> // variable declarations supressed. They are OK, believe me ;)
>
> XMLOutputter outputter = new XMLOutputter();
> Socket sock = new Socket("localhost",4445);
> outputter.output(inputDoc,sock.getOutputStream());
> sock.getInputStream().read(); // This is a dummy byte sent by socket to
> say "OK, I finished."
Finished what? Finished reading your output document and is now busy
writing the response?
> Thread.currentThread().sleep(1000);
Yuck! A "fine" example of Tore-Andersson-Principles-Of-Code-Writing.[*]
How do you know that the server will be finished within 1 second?
> byte[] socketThing = new byte[sock.getInputStream().available()];
> sock.getInputStream().read(socketThing);
So you read what the server app has currently written. That may not
always be the entire document.
> SAXBuilder builder = new SAXBuilder();
> Document doc = builder.build(new ByteArrayInputStream(socketThing));
Sometimes, randomly, you get a partial document and hence the "premature
end of file exception".
You cannot do it this way! There are two alternatives:
1) The server closes the connection when it has finished writing the
response. In that case the SAX parser will get an end of file and
finish properly. You can build directly from the socket's input stream.
2) The server keeps the connection open. In this case you must employ
some sort of 'protocol' to establish when the entire input is read. You
cannot build directly from the socket input stream, since the parser
reads chunks (2 or 4KB) of bytes, and will probably stall reading the
last chunk. One solution is to have the server prepend the response with
the length in bytes.
Hope this helps!
/pmn
[*]
Tore Andersson was a 'famous' programmer who employed busy-count loops
when implementing timing sensitive serial protocols for a shop-floor
application. Well, he became famous because of it.
Guess what happened when we upgraded the hardware? He's probably not
reading this now, but if he does, he deserves it. And it is not his
real name, anyway.
More information about the jdom-interest
mailing list