How do I send an HTTP response without Transfer Encoding: chunked?
Asked Answered
W

3

5

I have a Java Servlet that responds to the Twilio API. It appears that Twilio does not support the chunked transfer that my responses are using. How can I avoid using Transfer-Encoding: chunked?

Here is my code:

// response is HttpServletResponse
// xml is a String with XML in it
response.getWriter().write(xml);
response.getWriter().flush();

I am using Jetty as the Servlet container.

Warrantable answered 13/5, 2013 at 23:22 Comment(2)
What is your Application Server / Servlet Container?Carn
@AnthonyAccioly eclipse.org/jettyWarrantable
C
6

Try setting the Content-length before writing to the stream. Don't forget to calculate the amount of bytes according to the correct encoding, e.g.:

final byte[] content = xml.getBytes("UTF-8");
response.setContentLength(content.length);
response.setContentType("text/xml"); // or "text/xml; charset=UTF-8"
response.setCharacterEncoding("UTF-8");

final OutputStream out = response.getOutputStream();
out.write(content);
Carn answered 13/5, 2013 at 23:56 Comment(2)
setCharacterEncoding is probably not necessary since you are writing raw bytes. content type should include encoding: "text/xml; charset=UTF-8".Defile
Thanks @zhong.j.yu, updated the answer with your suggestion... User can either set the charset directly with the MIME type or use setCharacterEncoding which will override the Content-type header.Carn
C
7

I believe that Jetty will use chunked responses when it doesn't know the response content length and/or it is using persistent connections. To avoid chunking you either need to set the response content length or to avoid persistent connections by setting "Connection":"close" header on the response.

Centime answered 13/5, 2013 at 23:52 Comment(4)
Beat me to it. @Adam, if my code works, please accept cmbaxter answer.Carn
@AnthonyAccioly, now that is classy SO etiquetteDownandout
@AnthonyAccioly I will up-vote cmbaxter's answer. But, I was really looking for a code sample that showed what content length to set, so your answer is better despite the fact that both are correct, therefore I will accept yours.Warrantable
In my case Connection: close suppresses chunking, but then Jersey isn't supplying Content-Length, even though my MessageBodyWriter returns a non-negative getSize. I can set it myself, but then if the response is gzip-encoded, my Content-Length will be wrong and Jersey removes it.Blowpipe
C
6

Try setting the Content-length before writing to the stream. Don't forget to calculate the amount of bytes according to the correct encoding, e.g.:

final byte[] content = xml.getBytes("UTF-8");
response.setContentLength(content.length);
response.setContentType("text/xml"); // or "text/xml; charset=UTF-8"
response.setCharacterEncoding("UTF-8");

final OutputStream out = response.getOutputStream();
out.write(content);
Carn answered 13/5, 2013 at 23:56 Comment(2)
setCharacterEncoding is probably not necessary since you are writing raw bytes. content type should include encoding: "text/xml; charset=UTF-8".Defile
Thanks @zhong.j.yu, updated the answer with your suggestion... User can either set the charset directly with the MIME type or use setCharacterEncoding which will override the Content-type header.Carn
C
1

The container will decide itself to use Content-Length or Transfer-Encoding basing on the size of data to be written by using Writer or outputStream. If the size of the data is larger than the HttpServletResponse.getBufferSize(), then the response will be trunked. If not, Content-Length will be used.

In your case, just remove the 2nd flushing code will solve your problem.

Constanceconstancia answered 9/9, 2013 at 8:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.