java - respuesta - getwriter() has already been called for this response
java.lang.IllegalStateException: getOutputStream() ya se ha llamado para esta respuesta (11)
Obtengo la siguiente excepción cuando intento solicitar la carga de imágenes del servidor en el lado del cliente:
241132533 [TP-Processor1] ERROR [/jspapps].[jsp] - Servlet.service () para servlet jsp lanzó excepción java.lang.IllegalStateException: getOutputStream () ya se ha llamado para esta respuesta
¿Puede alguien explicarme esta excepción y también cómo superarla?
¿Alguien puede explicarme esta excepción?
Está intentando escribir datos binarios en response.getOutputStream()
usando código Java sin procesar dentro de un archivo JSP que ya está utilizando response.getWriter()
para escribir cualquier texto de plantilla. Ver también la parte Lanzamientos de los javadocs enlazados.
y también cómo superarlo?
Escriba código Java en una clase Java real en su lugar. Cree una clase que extends
HttpServlet
, mueva todo ese código Java allí, web.xml
en web.xml
y cambie la URL de solicitud para llamar al servlet.
Ver también:
Acabo de encontrar el mismo problema en mi trabajo reciente.
Tenemos un filtro de servlet en el que usamos el método ServletResponse.getWriter () para escribir el cuerpo, y en algún controlador Spring MVC, también usamos response.getOutputStream () para escribir algo como imágenes (matriz de bytes) en el cuerpo.
Dado que cada solicitud se filtrará y se basará en el documento de la API de Java:
"O este método (getWriter ()) o getOutputStream () se pueden llamar para escribir el cuerpo, no ambos".
Esa es la razón por la que obtuvimos la excepción "java.lang.IllegalStateException: getOutputStream () ya se ha llamado para esta respuesta".
Entonces en ese filtro, cambié el código a:
ServletOutputStream sos = response.getOutputStream();
sos.write(newHtml.getBytes("UTF8")); // newHtml is a String.
sos.flush();
Me solucionó este problema.
Acabo de tropezar con esta vieja pregunta ya que tenía el mismo problema. Al final fue bastante fácil deshacerse de la excepción: simplemente llama out.clear()
antes:
out.clear();
...
// later, in a different method
ServletOutputStream out = response.getOutputStream();
...
out.clear()
también me ayudó a deshacerme de todas esas líneas vacías de <%@page import=...
y out.clear()
el estilo.
Asegúrese de eliminar todos los resultados en su view_image.jsp
. Los saltos de línea simples pueden ser responsables de generar resultados.
Por ejemplo, si tiene estos declarions ...
<%@ page import ... %>
<%@ page import ... %>
... deberías escribirlos de esta manera
<%@ page import ... %><%@ page import ... %><%
...%>
Si out.write("/r/n")
un vistazo al código del servlet compilado, no deberías ver out.write("/r/n")
antes de la respuesta de tu imagen.
Una forma mejor sería cambiar su view_image.jsp
en un servlet, pero si no puede hacerlo, eliminar los saltos de línea en jsp es una solución alternativa.
Convierta view_image.jsp en un servlet mapeado en ViewImage
y ViewImage
como
<img src=''<%= request.getContextPath() %>/ViewImage?pat_acc=<%=Pat_Acct%>'' style=''position: absolute; left: 0pt; top: 0px;'' "/>
en tu archivo JSP.
En Spring, puedes resolver este problema cambiando
response.getOutputStream().write(cabecera.getBytes());
a
response.getWriter().write(cabecera);
Pruebe esto, aunque no es la mejor solución, pero funciona.
in.close();
out2.flush();
out.clear();
out = pageContext.pushBody();
Donde ''in'' es el InputStream (si lo está usando), ''out2'' es la nueva response.getOutputStream()
y ''out'' es el JspWriter
predeterminado.
Tenía este código y lo arreglé así:
@RequestMapping(value = "xyz", method = RequestMethod.POST)
public String generateReport(HttpServletResponse response, @Valid @ModelAttribute Form form, Errors errors, Model model) {
if (errors.hasErrors()) {
model.addAttribute(form);
return "abcd/xyz";
} else {
someMethodWhichUsesResponse(response);
}
Earlier:
return "abcd/xyz";
Fixed by:
return null;
}
Volví nulo porque, de este método, esperaba una descarga. Según la explicación dada aquí , arreglé mi problema.
intente eliminar todos los textos de plantilla del archivo jsp. por ejemplo,
1 <%@
2 ....
3 %>
4 <%
5 ....
6 %>
hay una ''/ n'' entre la línea 3 y 4, y se trata como texto de plantilla, se llama a response.getWriter () para escribir ''/ n'' en el cliente. después de la línea 6, también podría haber espacios en blanco invisibles que arruinarán la salida de salida. pero la línea 5 puede return
temprano para evitar eso.
si se enfrenta a este problema en servlets, entonces, al enviar la respuesta al servlet del navegador:
PrintWriter out=response.getWriter();
Esta debería ser la primera declaración después de que puedas escribir tu código html en el servlet que eventualmente será enviado al navegador
<%@page import="java.sql.DriverManager"%>
<%@page import="java.io.InputStream"%>
<%@page import="java.sql.Connection"%>
<%@page import="java.sql.PreparedStatement"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.Statement"%>
<%
Connection con=null;
ResultSet rs = null;
Statement st = null;
String sql = null;
try {
Class.forName("com.mysql.jdbc.Driver");
con=DriverManager.getConnection("test","root","root");
st = con.createStatement();
sql = "select image from projects where projectid=''1''";
System.out.println(sql);
rs = st.executeQuery(sql);
String imgLen = "";
out.clear();
while (rs.next())
{
imgLen = rs.getString(1);
System.out.println(imgLen.length());
int len = imgLen.length();
byte[] rb = new byte[len];
InputStream readImg = rs.getBinaryStream(1);
int index = readImg.read(rb, 0, len);
response.reset();
response.setContentType("image/jpg");
response.getOutputStream().write(rb, 0, len);
response.getOutputStream().flush();
response.getOutputStream().close();
}
st.close();
rs.close();
if (true) return;
} catch (Exception e) {e.printStackTrace();}
%>