2011-02-18 31 views
25

¿Debo "descargar" OutputStream desde HttpServletResponse?¿Debo limpiar la salida del servlet?

Ya vi desde Should I close the servlet outputstream? que no necesito cerrarlo, pero no está claro si necesito enjuagarlo. ¿Debería esperarlo del contenedor también?

protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException { 
    byte[] response = getResponse(); 
    String responseType = getResponseType(); 

    response.setContentLength(response.length); 
    response.setContentType(responseType); 
    response.getOutputStream().write(response); 
    response.getOutputStream().flush(); // yes/no/why? 
} 

Respuesta

37

No es necesario. El servletcontainer se vaciará y cerrará por usted. El cierre por el camino ya implícitamente llama flush.

Ver también el capítulo 5.6 de Servlet 3.1 specification:

5,6 Cierre del objeto respuesta

Cuando una respuesta se cierra, el contenedor debe lavar inmediatamente la todo el contenido que queda en la memoria de respuesta al cliente. Los siguientes eventos indican que el servlet ha satisfecho la solicitud y que el objeto de respuesta ha de ser cerrada:

  • La terminación del procedimiento de la servlet service.
  • La cantidad de contenido especificado en el setContentLength o setContentLengthLong método de la respuesta ha sido mayor que cero y se ha escrito en la respuesta.
  • Se llama al método sendError.
  • Se llama al método sendRedirect.
  • Se llama al método complete en AsyncContext.

llamadas durante ras todavía se está ejecutando el servicio del servlet es por lo general sólo es beneficioso cuando se tienen varios escritores sobre la misma corriente y que desea cambiar del escritor (por ejemplo, los archivos de datos binarios/carácter mixto), o cuando Desea mantener el puntero de flujo abierto durante un tiempo incierto (por ejemplo, un archivo de registro).

+0

¿Está esto basado en la convención (por @mdrg), o está documentado en alguna parte? – shmosel

+0

@shmosel: Actualicé la respuesta para incluir una cita de la especificación. – BalusC

2

Supongo que la misma respuesta que obtuvo en su otra pregunta se aplica aquí: si se trata de su corriente, enjuague y ciérrela. De lo contrario, el creador del flujo debería hacerlo, a menos que se indique lo contrario.

1
java.lang.Object 
    extended byjava.io.Writer 
     extended byjavax.servlet.jsp.JspWriter 


close 
public abstract void close() 
        throws IOException 
Close the stream, flushing it first. 
This method needs not be invoked explicitly for the initial JspWriter as the code generated by the JSP container will automatically include a call to close(). 

Closing a previously-closed stream, unlike flush(), has no effect. 


Throws: 
IOException - If an I/O error occurs 

============================ 

So, DO NOT close the output stream explicitly. 
0

Observar una excepción insidiosa a la regla de “no hay necesidad de limpiar”: Trabajar con IBM WebSphere Application Server y utilizando la respuesta escritor (en lugar de la OutputStream) me di cuenta que tenía que tirar de la cadena; de lo contrario, se perdió una parte final de mis datos de respuesta. Supongo que la clase HttpServletResponse de IBM en realidad vacía el OutputStream pero usa un buffer separado para el Writer y no lo vacía. Otros servidores de aplicaciones parecen hacer esto.

Por lo tanto, si envía sus datos de respuesta al Writer, es más seguro enjuagarlo. Pero no hay necesidad de enjuagar el OutputStream en la negociación.

(habría publicado esto como un comentario pero carezco de la reputación para hacerlo.)

Cuestiones relacionadas