Java Servlet HttpResponse contentLenght Header

2019-08-07 09:54发布

问题:

What happen if I do not specify the contentLenght header when I send a HttpResponse containing a zip file.

I did some tests and it seems that the header is set by default with the correct file lenght. Can I be sure that this always happens. When I can found some documentation about?

this is the most important part of the code:

    response.setContentType("application/zip");
            response.addHeader("Content-disposition", "attachment; filename=" + zipFileName);
        zos.close();
        out.close();
        response.flushBuffer(); 

Davide

回答1:

If the actual response content length fits entirely in the response buffer, which is usually 2KB (it depends on server make/version/config), then the content length header will be set. However, if the actual response content length is larger than the response buffer, so that it would be flushed sooner than the end of response content is reached, then the servlet will send the response with chunked encoding and ignore any attempts to set the content length header.

This is mentioned in among others the javadoc of HttpServlet#doGet() which is cited below:

...

Where possible, set the Content-Length header (with the ServletResponse.setContentLength(int) method), to allow the servlet container to use a persistent connection to return its response to the client, improving performance. The content length is automatically set if the entire response fits inside the response buffer.

When using HTTP 1.1 chunked encoding (which means that the response has a Transfer-Encoding header), do not set the Content-Length header.

...

With "normal" encoding, the data is sent as one continuous block.

actualContent

With chunked encoding, the data is sent in chunks which look like this

part1LengthInHexadecimal
actualPart1Content

part2LengthInHexadecimal
actualPart2Content

part3LengthInHexadecimal
actualPart3Content

0

The part length in hexadecimal indicates the client how large the next chunk of data is (so that it won't "accidently" parse the next chunk as part of current chunk). Finally, the client glues the parts together.

See also the example in wikipedia.