Alvin Baena
Alvin Baena

Reputation: 903

Weird JAX-RS Behavior

I'm making a web service that transmits an image file to a client. For the client I use the Apache HttpClient API, because I'm testing the services before starting to code on android.

Image Sent Image Recieved

As you can see, half(or so) of the pixels are lost in transfer, but I don't know if it's because of some transfer thieves or I'm parsing the answer wrong (probably the latter). I'm using SAX for the parse, it receives an InputStream in the form of XML.

The XML format is like this:

<Image>
    <data>some Base64 encoded bytes</data>
    <name>image name</name>
</Image>

Here is the web service client code:

private static void download() {
        try {
            System.out.println("Downloading file...");

            HttpClient client = new DefaultHttpClient();
            HttpGet request = new HttpGet(SERVICE_URL + "download/me");

            HttpResponse response = client.execute(request);

            if (response.getStatusLine().getStatusCode() != 200) {
                System.out.println("Error: HTTP error code: "
                        + response.getStatusLine().getStatusCode());
            }

            InputStream xml = response.getEntity().getContent();
            Image i = parseDownload(xml);
            System.out.println(i);

            client.getConnectionManager().shutdown();

            FileOutputStream fos = new FileOutputStream(
                    new File("D:/newMe.jpg"));
            fos.write(i.getData());
            fos.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Here is my parsing code:

private static Image parseDownload(InputStream xml) {
        final Image i = new Image();
        try {
            SAXParserFactory spf = SAXParserFactory.newInstance();
            SAXParser parser = spf.newSAXParser();

            DefaultHandler handler = new DefaultHandler() {
                private boolean name = false;
                private boolean data = false;

                @Override
                public void startElement(String uri, String localName,
                        String qName, Attributes attributes)
                        throws SAXException {
                    if (qName.equals("name"))
                        name = true;
                    if (qName.equals("data"))
                        data = true;
                }

                @Override
                public void characters(char[] ch, int start, int length)
                        throws SAXException {
                    if (name) {
                        i.setName(new String(ch, start, length));
                        name = false;
                    }
                    if (data) {
                        String data = new String(ch, start, length);
                        i.setData(Base64.decodeBase64(data));
                        this.data = false;
                    }
                }
            };

            Reader reader = new InputStreamReader(xml);

            InputSource is = new InputSource(reader);
            is.setEncoding("UTF-8");

            parser.parse(is, handler);
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return i;
    }

Any idea of what I'm doing wrong?

Upvotes: 2

Views: 165

Answers (1)

jtahlborn
jtahlborn

Reputation: 53694

Yes, you will see this answer time and time again on this site and many others: the characters() method call is not guaranteed to give you all the content of an element in 1 method call. you must aggregate all characters method calls into one buffer and only process them when you get the endElement() method call.

Upvotes: 3

Related Questions