0

I'm trying to make multiple calls to a REST API using HttpURLConnection with GET method and retrieving the response through InputStream.

It worked fine previously for 3 months but now it's throwing below exception:

SAXException Occurred during getArtifactsUrl method:: org.xml.sax.SAXParseException; Premature end of file. at org.apache.xerces.parsers.DOMParser.parse(Unknown Source) [xercesImpl.jar:6.1.0.Final] at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source) [xercesImpl.jar:6.1.0.Final] at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:121) [:1.7.0_03]

Below is the line of code where I'm making the second call to parse the response:

request = (HttpURLConnection) endpointUrl.openConnection();             
inputstream = request.getInputStream();             
doc = dBuilder.parse(inputstream);

First call is working fine using request and inputstream objects but second call is failing. I tried all possible answers I found in google but no luck: after every call:

inputstream.close();
request.disconnect();

Remember that request is an HttpURLConnection object.

I greatly appreciate if you can be able to solve this as I this is a high prioirity production issue now!

Martin Davies
  • 4,436
  • 3
  • 19
  • 40

1 Answers1

0

First you should check for error cases and not assume it's always working.

Try this:

request = (HttpURLConnection) endpointUrl.openConnection();             

request.connect(); // not really necessary (done automatically)
int statusCode = request.getResponseCode();
if (statusCode == 200) { // or maybe other 2xx codes?

    // Success - should work if server gives good response
    inputstream = request.getInputStream();

    // if you get status code 200 and still have the same error, you should
    // consider logging the stream to see what document you get from server.
    // (see below *)

    doc = dBuilder.parse(inputstream);

} else {

    // Something happened

    // handle error, try again if it makes sense, ...
    if (statusCode == 404) ... // resource not found 
    if (statusCode == 500) ... // internal server error

    // maybe there is something interesting in the body

    inputstream = request.getErrorStream();
    // read and parse errorStream (but probably this is not the body
    // you expected)

}

Have a look at the List of HTTP status codes.

And in some nasty cases, there are other problems which are not easy to detect if you just sit behind HttpURLConnection. Then you could enable logging or snoop the TCP/IP traffic with an apropriate tool (depends on your infrastructure, rights, OS, ...). This SO post might help you.

*) In your case I suppose that you're getting a non-error status code from the server but unparseable XML. If logging the traffic is not your thing, you could read the InputStream, write it to a file and then process the stream like before. Of course you can write the stream to a ByteArrayOutputStream, get the byte[] and write that Bytes to a file and then convert them to a ByteArrayInputStream and give this to your XML-parser. Or you could use Commons IO TeeInputStream to handle that for you.

There are cases where connection.getResponseCode() throws an exception. Then it was not possible to parse the HTTP header. This should only happen if there are strange errors in server software, hardware or perhaps a firewall, proxy or load balancer not behaving well.

One more thing: You might consider choosing an HTTP Client library and not directly use HttpURLConnection.

Community
  • 1
  • 1
hgoebl
  • 12,637
  • 9
  • 49
  • 72
  • Sorry for this late response. I figured out that the issue is with the response code of 302 from our second service call. So, need to check with the other partner and handle it accordingly in our code. But thanks for your answer to this and I recommend the same as above you did when you're trying to call the RESTful service using HttpURLConnection. – user3242315 Jan 30 '14 at 02:01
  • You can call `HttpURLConnection.setInstanceFollowRedirects(true)` then you don't have to handle it manually. But this works only when there is no switch of protocol (http -> https or vv.) and when using GET requests. (BTW on Android it depends on the version.) – hgoebl Jan 30 '14 at 06:58
  • That's right but in our case it's the switch of protocol (http -> https), so need to handle it accordingly in our code. – user3242315 Jan 30 '14 at 21:00