Raw XML Push from input stream captures only the first line of XML
I'm trying to read XML that is being pushed to my java app. I originally had this in my glassfish server working. The working code in glassfish is as follows:
public class XMLPush implements Serializable
{
public void processXML()
{
StringBuilder sb = new StringBuilder();
BufferedReader br = null;
try
{
br = ((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getReader ();
String s = null;
while((s = br.readLine ()) != null)
{
sb.append ( s );
}
//other code to process xml
...........
.............................
}catch(Exception ex)
{
XMLCreator.exceptionOutput ( "processXML","Exception",ex);
}
....
.....
}//processXML
}//class
It works perfect, but my client is unable to have glassfish on their server. I tried grabbing the raw xml from php, but I couldn't get it to work. I decided to open up a socket and listen for the xml push manually. Here is my code for receiving the push:
public class ListenerService extends Thread
{
private BufferedReader reader = null;
private String line;
public ListenerService ( Socket connection )thows Exception
{
this.reader = new BufferedReader ( new InputStreamReader ( connection.getInputStream () ) );
this.line = null;
}//ListenerService
@Override
public void run ()
{
try
{
while ( (this.line = this.reader.readLine ()) != null)
{
开发者_JAVA百科System.out.println ( this.line );
........
}//while
} System.out.println ( ex.toString () );
}
} catch ( Exception ex )
{
...
}//catch
}//run
I haven't done much socket programing, but from what I read for the past week is that passing the xml into a string is bad. What am I doing wrong and why is it that in glassfish server it works, and when I just open a socket myself it doesn't?
this is all that I receive from the push:
PUT /?XML_EXPORT_REASON=ResponseLoop&TIMESTAMP=1292559547 HTTP/1.1
Host: ************************
Accept: */*
Content-Length: 470346
Expect: 100-continue
<?xml version="1.0" encoding="UTF-8" ?>
Where did the xml go? Is it because I am placing it in a string? I just need to grab the xml and save it into a file and then process it. Everything else works, but this.Any help would be greatly appreciated.
I think the key here is this line in your push request:
100-continue
From the HTTP/1.1 specifications:
The purpose of the 100 (Continue) status (see section 10.1.1) is to allow a client that is sending a request message with a request body to determine if the origin server is willing to accept the request (based on the request headers) before the client sends the request body. In some cases, it might either be inappropriate or highly inefficient for the client to send the body if the server will reject the message without looking at the body.
When you go through GlassFish (or some other technology which implements the HTTP standards), that middleware will handle all the negotiations to ensure that by the time the request gets to your code, you have everything you're able to accept. Because you're reading direct from the Socket in your example though, you have nothing between you and the client handling the HTTP negotiations, so you only get the first little bit and a '100-continue' waiting for the go-ahead.
The first line of the XML had a line terminator (\r\n), but the rest of the XML did not. This is the reason why my threads would get stuck. I used
BufferedReader reader;
int i;
while((i = reader.read()) != -1)
and casted it into char:
StringBuilder sb = new StringBuilder();
sb.append((char)i);
and stuck all the data into an xml file I created and was able to do everything correctly.
The only thing is I had a similar problem at the end, so I had to check to see if I reached the end of the XML document. I just put the last 9 characters of the stream into an arraylist and checking it against the last part of what the XML file is supposed to end with. Works fine now, and the client (and I as well) is very happy. :) Hope this helps.
Oh one final note. I read that JDOM can actual use the input stream directly. I haven't tested it yet, but that would be more efficient to use, if the line termination will not be a problem either. Maybe someone else has used JDOM with inputstream and has had a line termination issue?
精彩评论