[jdom-interest] A problem about reading xml from socket

Laurent Bihanic laurent.bihanic at atosorigin.com
Fri Apr 4 01:14:09 PST 2003


alex wrote:
> In the FAQ,
> Why does passing a document through a socket sometimes hang the parser?
> 
> The problem is that several XML parsers close the input stream when they read EOF (-1). This is true of Xerces, which is JDOM's default parser. It is also true of Crimson. Unfortunately, closing a SocketInputStream closes the underlying SocketImpl, setting the file descriptor to null. The socket's output stream is useless after this, so your application will be unable to send a response. To workaround, protect your socket's input stream with an InputStream wrapper that doesn't close the underlying stream (override the close() method), or read everything into a buffer before handing off to the JDOM builder:
> 
> the following method is mentioned,but how can I calculate the "length"?
>     byte[] buf = new byte[length];
>     new DataInputStream(inputStream).readFully(buf);
>     InputStream in = new ByteArrayInputStream(buf);
>

Unfortunately, real life is a little bit more complicated as the length may
not be specified. Try the following.

    byte[] data = getRequestData(httpReq.getInputStream(),
httpReq.getContentLength());


    /**
     * Returns a byte array containing the data read from the HTTP
     * request input stream.
     *
     * @param  stream   the input stream to the content of the HTTP
     *                  request.
     * @param  length   the request content length.
     *
     * @return the request content as a byte array.
     *
     * @throws IOException if any error occurred while reading the
     *                     request content.
     */
    private byte[] getRequestData(InputStream stream, int length)
                                                          throws IOException
    {
        byte[] data = null;

        if (length != -1)
        {
            // Content length specified.
            data = new byte[length];

            new DataInputStream(stream).readFully(data);
        }
        else
        {
            // Content length not specified.
            // => Read content stream until an EOF is encountered.
            ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);

            int l;
            byte[] xfer = new byte[1024];
            while ((l = stream.read(xfer)) != -1)
            {
                baos.write(xfer, 0, l);
            }
            data = baos.toByteArray();
        }
        return data;
    }




More information about the jdom-interest mailing list