当我尝试请求从客户端的服务器加载图像时,我收到以下异常:
241132533 [TP-Processor1] ERROR [/jspapps].[jsp] - servlet jsp的Servlet.service()抛出异常 java.lang.IllegalStateException:已为此响应调用了getOutputStream()
任何人都可以向我解释这个例外以及如何克服它吗?
答案 0 :(得分:7)
任何人都可以向我解释这个例外
您正在尝试使用JSP文件中的原始Java代码将二进制数据写入response.getOutputStream()
,该文件本身已使用response.getWriter()
来编写任何模板文本。另请参阅链接的javadocs的投掷部分。
还有如何克服它?
将Java代码写入真正的Java类中。创建一个extends
HttpServlet
的类,将所有Java代码移到那里,将其映射到web.xml
并更改请求URL以调用servlet。
答案 1 :(得分:6)
我偶然发现了这个老问题,因为我有同样的问题。最后,很容易摆脱异常:只需在out.clear()
之前调用:
out.clear();
...
// later, in a different method
ServletOutputStream out = response.getOutputStream();
...
out.clear()
也帮助我摆脱了<%@page import=...
之类的所有空行。
答案 2 :(得分:2)
确保消除view_image.jsp
中的所有输出。简单的换行符可以负责生成输出。
例如,如果你有这些声明......
<%@ page import ... %>
<%@ page import ... %>
......你应该这样写它
<%@ page import ... %><%@ page import ... %><%
...%>
如果您查看已编译的servlet代码,则在图像响应之前不应该看到out.write("\r\n")
。
更好的方法是将view_image.jsp
更改为Servlet,但如果不能这样做,删除jsp中的换行符就是一种解决方法。
答案 3 :(得分:1)
试试这个,虽然它不是最好的解决方案,但它确实有效。
in.close();
out2.flush();
out.clear();
out = pageContext.pushBody();
其中'in'是InputStream(如果您正在使用它),'out2'是新的response.getOutputStream()
,'out'是默认的JspWriter
。
答案 4 :(得分:1)
<%@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();}
%>
答案 5 :(得分:0)
将view_image.jsp转换为映射到ViewImage
的Servlet,并将其称为
<img src='<%= request.getContextPath() %>/ViewImage?pat_acc=<%=Pat_Acct%>' style='position: absolute; left: 0pt; top: 0px;' "/>
在JSP文件中。
答案 6 :(得分:0)
尝试从jsp文件中删除所有模板文本。例如,
1 <%@
2 ....
3 %>
4 <%
5 ....
6 %>
第3行和第4行之间有一个'\ n',它被视为模板文本,调用response.getWriter()将'\ n'写入客户端。在第6行之后,也可能存在不可见的空格,这会使输出流搞砸。但是第5行可以提前return
来避免这种情况。
答案 7 :(得分:0)
我刚刚在最近的工作中遇到了同样的问题。
我们有一个servlet过滤器,我们在其中使用ServletResponse.getWriter()方法来编写主体,在一些Spring MVC控制器中,我们还使用response.getOutputStream()将类似图像(字节数组)的内容写入正文
由于每个请求都将通过过滤器,并基于Java API doc:
“可以调用此方法(getWriter())或getOutputStream()来编写正文,而不是两者。”
这就是为什么我们得到“java.lang.IllegalStateException:getOutputStream()已被调用此响应”异常。
因此,在该过滤器中,我将代码更改为:
ServletOutputStream sos = response.getOutputStream();
sos.write(newHtml.getBytes("UTF8")); // newHtml is a String.
sos.flush();
它为我解决了这个问题。
答案 8 :(得分:0)
在Spring中,您可以解决此问题的更改
response.getOutputStream().write(cabecera.getBytes());
到
response.getWriter().write(cabecera);
答案 9 :(得分:0)
我有这个代码并修改如下:
@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;
}
我返回null,因为从这种方法来看,我期待下载。根据{{3}}给出的解释,我解决了我的问题。
答案 10 :(得分:0)
如果您在servlet中遇到此问题,那么在从servlet发送响应到浏览器时:
PrintWriter out=response.getWriter();
这应该是你可以在servlet中编写最终发送到浏览器的html代码的第一个语句