Menu

java http file upload tickets

Not long ago, I developed a java http file upload model.
One things to notice here.
1.the size limited

-----------------------analysis-------------------------

1.Normally,HttpConnection use BufferedStream to buffer in local,When it's buffer is too big,then it will Out Of Memory.
we see across analysing source code that there are two ways to avoid this.
1.1 public void setFixedLengthStreamingMode (int contentLength){}
/*
* This method is used to enable streaming of a HTTP request body
* without internal buffering, when the content length is not
* known in advance. In this mode, chunked transfer encoding
* is used to send the request body. Note, not all HTTP servers
* support this mode.
*


* When output streaming is enabled, authentication
* and redirection cannot be handled automatically.
* A HttpRetryException will be thrown when reading
* the response if authentication or redirection are required.
* This exception can be queried for the details of the error.
*


* This method must be called before the URLConnection is connected.
*
* @param chunklen The number of bytes to write in each chunk.
* If chunklen is less than or equal to zero, a default
* value will be used.
*
* @throws IllegalStateException if URLConnection is already connected
* or if a different streaming mode is already enabled.
*
* @see #setFixedLengthStreamingMode(int)
* @since 1.5
/
public void setChunkedStreamingMode (int chunklen) {
if (connected) {
throw new IllegalStateException ("Can't set streaming mode: already connected");
}
if (fixedContentLength != -1) {
throw new IllegalStateException ("Fixed length streaming mode set");
}
chunkLength = chunklen <=0? DEFAULT_CHUNK_SIZE : chunklen;
}

1.2 public void setChunkedStreamingMode (int chunklen){}
/*
* This method is used to enable streaming of a HTTP request body
* without internal buffering, when the content length is not
* known in advance. In this mode, chunked transfer encoding
* is used to send the request body. Note, not all HTTP servers
* support this mode.
*


* When output streaming is enabled, authentication
* and redirection cannot be handled automatically.
* A HttpRetryException will be thrown when reading
* the response if authentication or redirection are required.
* This exception can be queried for the details of the error.
*


* This method must be called before the URLConnection is connected.
*
* @param chunklen The number of bytes to write in each chunk.
* If chunklen is less than or equal to zero, a default
* value will be used.
*
* @throws IllegalStateException if URLConnection is already connected
* or if a different streaming mode is already enabled.
*
* @see #setFixedLengthStreamingMode(int)
* @since 1.5
/
public void setChunkedStreamingMode (int chunklen) {
if (connected) {
throw new IllegalStateException ("Can't set streaming mode: already connected");
}
if (fixedContentLength != -1) {
throw new IllegalStateException ("Fixed length streaming mode set");
}
chunkLength = chunklen <=0? DEFAULT_CHUNK_SIZE : chunklen;
}

1.3 let's see sun.net.www.protocol.http package

    public class HttpURLConnection extends java.net.HttpURLConnection

    /*
     * Allowable input/output sequences:
     * [interpreted as POST/PUT]
     * - get output, [write output,] get input, [read input]
     * - get output, [write output]
     * [interpreted as GET]
     * - get input, [read input]
     * Disallowed:
     * - get input, [read input,] get output, [write output]
     */

    public synchronized OutputStream getOutputStream() throws IOException {

        try {
            if (!doOutput) {
                throw new ProtocolException("cannot write to a URLConnection"
                               + " if doOutput=false - call setDoOutput(true)");
            }

            if (method.equals("GET")) {
                method = "POST"; // Backward compatibility
            }
            if (!"POST".equals(method) && !"PUT".equals(method) &&
                "http".equals(url.getProtocol())) {
                throw new ProtocolException("HTTP method " + method +
                                            " doesn't support output");
            }

            // if there's already an input stream open, throw an exception
            if (inputStream != null) {
                throw new ProtocolException("Cannot write output after reading input.");
            }

            if (!checkReuseConnection())
                connect();

            /* REMIND: This exists to fix the HttpsURLConnection subclass.
             * Hotjava needs to run on JDK1.1FCS.  Do proper fix in subclass
             * for 1.2 and remove this.
             */

            if (streaming() && strOutputStream == null) {
                writeRequests();
            }
            ps = (PrintStream)http.getOutputStream();
            if (streaming()) {
                if (strOutputStream == null) {
                    if (fixedContentLength != -1) {
                        strOutputStream = new StreamingOutputStream (ps, fixedContentLength);
                    } else if (chunkLength != -1) {
                        strOutputStream =
                            new StreamingOutputStream (new ChunkedOutputStream (ps, chunkLength), -1);
                    }
                }
                return strOutputStream;
            } else {
                if (poster == null) {
                    poster = new PosterOutputStream();//note: sun.net.www.http.PosterOutputStream extends ByteArrayOutputStream
                }
                return poster;
            }
        } catch (RuntimeException e) {
            disconnectInternal();
            throw e;
        } catch (IOException e) {
            disconnectInternal();
            throw e;
        }
    }

-----------------------------------result----------------------------------

so when we invoke setFixedLengthStreamingMode or setChunkedStreamingMode method and set it's value, It will avoid PosterOutputStream buffer, and avoid OOM.

Posted by chanser 2012-06-15

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.