views:

65

answers:

5

I'm having problem with sending XML-data using HTTP POST to an API.

If I send well formatted XML, I get an error message:

Server Exception: Cannot access a closed Stream

If the XML isn't well formatted, I get HTTP 500. And if I just send an empty string instead of a string with XML, I get back an error message: EMPTY REQUEST.

I don't have many ideas about what the error could be, but the connection works because the error message is returned in XML format. I'm just sending the XML data as a string. Is it possible that I am required to send an EOF or something in the end? And how do I do that in my Java code? Any other ideas about what the problem can be?

The API is made in .NET

Here is the Java code I'm using to POST the XML data:

  Authenticator.setDefault(new MyAuthenticator());
  String xmlRequestStatus = 
  "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><test><data>32</data></test>";
  System.out.println(xmlRequestStatus);
  String contentType = "text/xml";
  String charset = "ISO-8859-1";
  String request = null;
  URL url = null;
  HttpURLConnection connection = null;
  OutputStream output = null;
  InputStream response = null;
  try {
   url = new URL("http://127.0.0.1/test");
  } catch (MalformedURLException e) {
   e.printStackTrace();
  }

  try {
   connection = (HttpURLConnection)url.openConnection();
   connection.setDoOutput(true);
   connection.setRequestMethod("POST");
   connection.setRequestProperty("Accept-Charset", charset);
   connection.setRequestProperty("Content-Type", contentType);
   output = connection.getOutputStream();
   output.write(request.getBytes("ISO-8859-1"));
   if(output != null) try { output.close(); } catch (IOException e) {}

   response = connection.getInputStream();
        ....
A: 

You need to specify method POST by doing something like this,

 connection.setRequestMethod("POST");
 connection.setRequestProperty("Content-Length", "" + length);

Otherwise, it's treated as a GET and some server doesn't expect body with GET so the stream is closed.

ZZ Coder
Thanks, I added that, but got the same problem. I use the code from this answer: http://stackoverflow.com/questions/2793150/how-to-use-java-net-urlconnection-to-fire-and-handle-http-requests/2793153#2793153
Jonas
A: 

Maybe close the OutputStream later in the control flow. So instead of this:

output.write(request.getBytes("ISO-8859-1"));
if(output != null) try { output.close(); } catch (IOException e) {}

response = connection.getInputStream();

Try this (and maybe add the flush)?

output.write(request.getBytes("ISO-8859-1"));
output.flush();
response = connection.getInputStream();

if(output != null) try { output.close(); } catch (IOException e) {}
Julius Davies
Thanks, but it didn't help :(
Jonas
A: 

Shouldn't it be &lt;32 instead of <32?

Ha
Ah, it was just a typo by me, sorry. I have updated my question now. I get the same error message.
Jonas
A: 

It looks like request is initialized to null, but afterwards not set. Should it not be

output.write(xmlRequestStatus.getBytes("ISO-8859-1"));
Marc van Kempen
+1  A: 

It looks fine and should work fine. The connection.setRequestMethod("POST"); is however entirely superfluous when you already did connection.setDoOutput(true);.

Since this error is coming straight from the .NET webservice hosted at localhost, are you sure that it is written without bugs? I don't do .NET, but Google learns me that it's related to MemoryStream. I'd concentrate on the .NET code and retest/debug it. Maybe those related SO questions may help.

BalusC