Fwd: [jdom-interest] SAXBuilder.build() weirdness

Bob Tarling bobtarling at hotmail.com
Tue Jul 17 17:44:05 PDT 2001


>If I pass the xml document (via POST) to a servlet which calls
>the program it dies at the SAXBuilder.build(BufferedReader) call.
>The interesting thing is that the method just hangs.  There are no
>exceptions thrown by the build process.
>I was wondering if 1) anyone has encountered this behavior before
>and knows of a solution

I had similar problem experimenting with sending XML files through sockets. 
I pieced together an example solution based on some clues in the FAQ and 
various posts in the mailing list (plus some help from Suns java forums). 
However I found no simple example anywhere. Being new to XML/JDOM and pretty 
new to Java this would have helped me a great deal.

Basically, as far as I can make out, the problem is that the DOM parser 
doesn't always know when a stream coming in through a BufferedReader has 
ended. If your reading a file then fine, a file has a definite end. But if 
your reading in through a socket it just carries on waiting while the socket 
is open as it doesn't know if the client has finished. If the client closes 
the stream to indicate it's finished then the socket is closed and the 
server can't return a response. It can make no assumption when it hits the 
last tag because according to W3C there can still be processor instructions 
after this last tag. It just sits there waiting for these.

The attached solution sends the entire XML across the socket as a single 
string terminated by a line break. This is then transfered to a StringReader 
and the StreamReader can be accepted by the build as the string has a 
definite end.

In my simple example the client sends the file test.xml to the server and 
the server responds back with the name of the root element.

As I say I'm pretty new to this technology so others may correct me or be 
able to elaborate further.

The real solution, I believe, would be for the W3C to stipulate that the end 
tag is the end of document or to give us an alternative EOD marker. That way 
the XML parser could simply take the input stream direct from the socket 
without any need for manipulation to make it work.

Maybe the build function of SAXBuilder could be modified to take another 
argument which states an end of document marker.

Hope this helps

Bob.



>From: John Muhlestein <jmuhlestein at i-link.net>
>To: "'jdom-interest at jdom.org'" <jdom-interest at jdom.org>
>Subject: [jdom-interest] SAXBuilder.build() weirdness
>Date: Tue, 17 Jul 2001 15:56:39 -0600
>
>Along with my transformation problems (and the reason I discovered them --
>previous post) is because I have an xml document which does not finish
>parsing.  Here is the scenario, I have a Class that takes in a
>BufferedReader and, among other things, creates a JDOM Document from the
>BufferedReader.  If I call this class from a program which opens the xml
>from a document everthing works great.  If I pass the xml document (via
>POST) to a servlet which calls the program it dies at the
>SAXBuilder.build(BufferedReader) call.  The interesting thing is that the
>method just hangs.  There are no exceptions thrown by the build process.
>
>I was wondering if 1) anyone has encountered this behavior before and knows
>of a solution and if not, 2) is there a good way to watch the SAX events
>while the JDOM document is being built to see if it a particular bit of
>content that it is getting hung up on.
>
>thanks again,
>
>John
>_______________________________________________
>To control your jdom-interest membership:
>http://lists.denveronline.net/mailman/options/jdom-interest/youraddr@yourhost.com

_________________________________________________________________________
Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com.
-------------- next part --------------
import java.net.*;
import java.io.*;

public class ClientTest {
	public static final int PORT = 8082;

	public static void main(String[] args) {
		ClientTest clientTest = new ClientTest();
		clientTest.sendFile("test.xml");
	}

	public void sendFile (String filename) {
		try {
			InetAddress addr = InetAddress.getByName(null);
			Socket socket = new Socket(addr, PORT);
			try {
				BufferedReader in =
					new BufferedReader(new InputStreamReader(socket.getInputStream()));
				PrintWriter out =
					new PrintWriter(new BufferedWriter(
						new OutputStreamWriter(socket.getOutputStream())),false);

				FileInputStream is = new FileInputStream(filename);

				// Create a buffered reader to read the file line by
				// line and send to ouput stream without line breaks.
				BufferedReader file = new BufferedReader(new InputStreamReader(is));
				String s;
				while((s = file.readLine()) != null) {
					out.print(s);
				}
				file.close();

				// Send a line break as terminator and then flush
				out.println();
				out.flush();

				// Get response from server and display it.
				s = in.readLine();
				System.out.println(s);
			} finally {
				socket.close();
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
}

-------------- next part --------------
import java.util.*;
import java.io.*;
import java.net.*;
import org.jdom.*;
import org.jdom.input.*;

public class ServerTest {
	public static final int PORT = 8082;

	public static void main(String[] args) throws IOException {
		ServerTest serverTest = new ServerTest();
	}

	ServerTest () throws IOException {
		while(true) {
			ServerSocket s = new ServerSocket(PORT);
			System.out.println("Awaiting on socket " + s);
			try {
				Socket socket = s.accept();
				System.out.println("Accepted on socket " + s);
				try {
					BufferedReader br =
						new BufferedReader(new InputStreamReader(socket.getInputStream()));

					PrintWriter out =
						new PrintWriter(new BufferedWriter(
							new OutputStreamWriter(socket.getOutputStream())),true);

					// Read the entire XML in one string and pass this
					// as a String Reader to DOM
					StringReader sr = new StringReader (br.readLine());
					SAXBuilder builder = new SAXBuilder();
					Document doc = builder.build(sr);

					// Get the name of the root element and return this to the client
					// as a response.
					Element element = doc.getRootElement();
					String rootName = element.getName();
					out.println(rootName);

				} catch (Exception e) {
					e.printStackTrace();
				}
				socket.close();
			} finally {
				s.close();
			}
		}
	}
}



More information about the jdom-interest mailing list