2

Hi everyone am currently working on an application that needs to parse an xml document so as to authenticate users.Am using URLConnection class of the java.net.* package to connect to as specific URL which gives an returns its response in xml format. When i try to parse the document using jdom , i get the following error:
org.jdom2.input.JDOMParseException: Error on line 1: Premature end of file

Can anyone pinpoint the problem and assist me with a remedy? thanks, here is a section of my code

try {
  String ivyString = "http://kabugi.hereiam.com/?username=" + ivyUsername + "&password=" + ivyPassword;

  URL authenticateURL = new URL(ivyString);
  URLConnection ivyConnection = authenticateURL.openConnection();
  HttpURLConnection ivyHttp = (HttpURLConnection) ivyConnection;
  System.out.println("Response code ==>" + ivyHttp.getResponseCode());
  if (ivyHttp.getResponseCode() != 200) {
    ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Invalid username or password!", ""));
    page = "confirm.xhtml";
  } else {
    BufferedReader inputReader = new BufferedReader(new InputStreamReader(ivyConnection.getInputStream()));
    String inline = "";
    while ((inline = inputReader.readLine()) != null) {
      System.out.println(inline);
    }
    SAXBuilder builder = new SAXBuilder();

    Document document = (Document) builder.build(ivyConnection.getInputStream());
    Element rootNode = document.getRootElement();
    List list = rootNode.getChildren("data");
    for (int i = 0; i < list.size(); i++) {
      Element node = (Element) list.get(i);
      System.out.println("Element data ==>" + node.getChildText("username"));
      System.out.println("Element data ==>" + node.getChildText("password"));

    }

    page = "home.xhtml";
  }
} catch (Exception ex) {
  ex.printStackTrace();
  // ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Invalid username or password!", ""));
}
athspk
  • 6,722
  • 7
  • 37
  • 51
bugiman
  • 21
  • 1
  • 1
  • 3
  • 1
    The problem could simply be that the data returned by the inputStream is badly formatted XML - have you checked the actual content? – matt b Sep 17 '12 at 20:22
  • As stated by @mattb, the content you are retrieving may not be a valid XML document. In order to parse HTML pages, you may use a more flexible library, for example JSoup, see: http://jsoup.org – Alex Sep 17 '12 at 20:26
  • Or you could use fluent API "RestAssured" or another project called "RestEasy"... – djangofan Sep 17 '12 at 20:32
  • @matt b thanks for the quick response, when i access the actual link on my browser, the xml seems to be well formed! – bugiman Sep 17 '12 at 20:45
  • It is not uncommon for some services to produce different data depending on the 'client'. You need to 'dump' the content of the URLConnection to ensure that what you see in a browser is the same as what the server sends to your non-browser application. – rolfl Sep 17 '12 at 21:44
  • In the code you are reading the stream twice. If you want to look at the stream data you must read it into a string, print it and then create a new `InputStream` around a `StringReader` to hand on to the parser. – OldCurmudgeon Sep 17 '12 at 21:50
  • @OldCurmudgeon you've actually solved my problem!! – bugiman Sep 17 '12 at 22:30
  • gotten rid of BufferedReader inputReader = new BufferedReader(new InputStreamReader(ivyConnection.getInputStream())); String inline=""; while((inline=inputReader.readLine())!=null){ System.out.println(inline); } everythin's now ok! – bugiman Sep 17 '12 at 22:33
  • You may find a [FilteredInputStream](http://stackoverflow.com/a/8268698/823393) useful for debugging one day. – OldCurmudgeon Sep 17 '12 at 23:41

3 Answers3

5

Looks like its because you are reading the inputstream twice. Once to print it and next to build the document. When you come to the point where you build the Document object, the input stream is already read fully and at its end. Try the following code which reads the stream only once

        BufferedReader inputReader = new BufferedReader(new InputStreamReader(ivyConnection.getInputStream()));
        StringBuilder sb = new StringBuilder();
        String inline = "";
        while ((inline = inputReader.readLine()) != null) {
          sb.append(inline);
        }

        System.out.println(sb.toString());
        SAXBuilder builder = new SAXBuilder();

        Document document = (Document) builder.build(new ByteArrayInputStream(sb.toString().getBytes()));
maneesh
  • 1,092
  • 1
  • 8
  • 11
1

I have had a problem similar to this before. If its a uncompressed HTTP connection you can packet trace the packets using Wireshark. What you will probably find is that there is a unexpected XML BOM header (other other problem) at the beginning of the XML response data. This could happen, for example, if the HTTP library you use doesn't support http chunking or the xml is the wrong encoding.

We won't know until you analyze the traffic using a packet sniffer and identify the BOM header (or lack of a BOM header). In any case, if there is a problem, you can hack the stream to account for the BOM header.

djangofan
  • 28,471
  • 61
  • 196
  • 289
  • does it mean that the problem is being caused by the encoding declaration in the xml response ? – bugiman Sep 17 '12 at 21:06
  • That's what I think but it is possible there is another reason. You need to packet trace it to know for sure or print the stream to console before passing it to the builder. – djangofan Sep 18 '12 at 15:29
  • Had to edit my answer a little. java.net.* handles http chunking just fine. – djangofan Nov 19 '12 at 22:55
0

Using sax parse you can read the inputstream.

SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
ParseCustomer parseEventsHandler=new ParseCustomer();
sp.parse(ivyHttp.getInputStream(),parseEventsHandler);

Here ParseCustomer is the parse class that will read the xml. Given sample is:

class ParseCustomer extends DefaultHandler{
    @Override
    public void startDocument() throws SAXException {

        super.startDocument();
    }
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

        super.startElement(uri, localName, qName, attributes);//enter code here
        if (qName.equals("frameit")) {
            // compare element name and get value/ for further help read saxparser
            orderId=atts.getValue("orderId");
        }
        System.out.println(qName);

    }

    @Override
    public void endElement(String uri, String localName, String qName)
        throws SAXException {

        super.endElement(uri, localName, qName);
    }

    @Override
    public void characters(char[] ch, int start, int length)
        throws SAXException {

        super.characters(ch, start, length);
    }

}
Unni Kris
  • 3,081
  • 4
  • 35
  • 57