《轻量级J2EE企业应用实战》一书的第2章有一个使用SerlvetResponse输出图像的例子,代码如下:
<%
BufferedImage image = new BufferedImage(400, 400, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
g.fillRect(0,0,400,400);
g.setColor(new Color(255,0,0));
g.fillArc(20,20,100,100,30,120);
g.setColor(new Color(0,255,0));
g.fillArc(20,20,100,100,150,20);
g.setColor(new Color(0,0,255));
g.fillArc(20,20,100,100,270,120);
g.setColor(new Color(0,0,0));
g.drawString("red:climb" , 300, 80);
g.drawString("green:swim", 300, 120);
g.drawString("blue:jump", 300, 160);
ImageIO.write(image, "bmp", response.getOutputStream());
//out.clear();
//out = pageContext.pushBody();
%>
在Tomcat下运行时抛出如下异常:
at org.apache.catalina.connector.Response.getWriter(Response.java:601)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:196)
at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)
at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:185)
at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:116)
at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:76)
at org.apache.jsp.pages.drawImage_jsp._jspService(drawImage_jsp.java:84)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:328)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:315)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:210)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:870)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:685)
at java.lang.Thread.run(Thread.java:595)
查看转换后的JSP代码,发现第84行如下(绿色高亮处):
public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException, ServletException {
JspFactory _jspxFactory = null;
PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
Object page = this;
JspWriter _jspx_out = null;
PageContext _jspx_page_context = null;
try {
_jspxFactory = JspFactory.getDefaultFactory();
response.setContentType("text/html; charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\r\n");
out.write("\n");
out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n");
out.write("<html>\n");
out.write("<head>\n");
out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n");
out.write("<title>Draw Image</title>\n");
out.write("</head>\n");
out.write("<body>\n");
out.write("\r\n");
BufferedImage image = new BufferedImage(400, 400, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
g.fillRect(0,0,400,400);
g.setColor(new Color(255,0,0));
g.fillArc(20,20,100,100,30,120);
g.setColor(new Color(0,255,0));
g.fillArc(20,20,100,100,150,20);
g.setColor(new Color(0,0,255));
g.fillArc(20,20,100,100,270,120);
g.setColor(new Color(0,0,0));
g.drawString("red:climb" , 300, 80);
g.drawString("green:swim", 300, 120);
g.drawString("blue:jump", 300, 160);
ImageIO.write(image, "bmp", response.getOutputStream());
//out.clear();
//out = pageContext.pushBody();
out.write("\r\n");
out.write("</body>\n");
out.write("</html>");
} catch (Throwable t) {
if (!(t instanceof SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
out.clearBuffer();
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
}
} finally {
if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context);
}
}
我们看到在JSP页面释放资源的时候,调用了ServetResponse.getWriter()方法,之后程序即抛出异常了,查看Servlet的API发现问题:
public java.io.PrintWriter getWriter()
throws java.io.IOException
Returns a PrintWriter
object that can send character text to the client. The PrintWriter
uses the character encoding returned by getCharacterEncoding()
. If the response's character encoding has not been specified as described in getCharacterEncoding
(i.e., the method just returns the default value ISO-8859-1
), getWriter
updates it to ISO-8859-1
.
Calling flush() on the PrintWriter
commits the response.
Either this method or getOutputStream()
may be called to write the body, not both.
Returns:
a PrintWriter
object that can return character data to the client
Throws:
UnsupportedEncodingException
- if the character encoding returned by getCharacterEncoding
cannot be used
java.lang.IllegalStateException - if the getOutputStream method has already been called for this response object
java.io.IOException
- if an input or output exception occurred
See Also:
getOutputStream()
, setCharacterEncoding(java.lang.String)
如API所言,由于ServletResponse.getOutputStream()方法和该方法都有可能被调用,来输出JSP页面的内容,如果其中的一个方法被调用了,再调用另一个方法就会抛出异常。解决方法如下:
将JSP页面的最后两行代码的注释去掉,这两行代码的作用如下:
out.clear():清空缓存的内容。
pageContext.pushBody():参考API
public BodyContent pushBody()Return a new BodyContent object, save the current "out" JspWriter, and update the value of the "out" attribute in the page scope attribute namespace of the PageContext.
Returns:
the new BodyContent
·返回一个新的BodyContent(代表一个HTML页面的BODY部分内容)
·保存JspWriter实例的对象out
·更新PageContext的out属性的内容
分享到:
相关推荐
在Java Web开发中,"getOutputStream() has already been called for this response" 是一个常见的错误,通常出现在使用Servlet或JSP时。这个错误意味着在HTTP响应中,`getOutputStream()`已经被调用,然后尝试再次...
1.在tomcat6.0下jsp出现getOutputStream() has already been called for this response异常的原因和解决方法 在tomcat6.0下jsp中出现此错误一般都是在jsp中使用了输出流(如输出图片验证码,文件下载等),没有...
验证码出现getOutputStream() has already been called for this response错误解决
纠结了半天的 java.lang.IllegalStateException: getOutputStream() has already。这个问题困扰了半天,在网上查阅了大量资料 出这个错误一般就是下面2个.....
解决了getOutputStream() has already been called for this response. 并将产生验证码的逻辑从JSP页面中分离出来,单独写了一个类 便于重用。
解决“Cannot forward after response has been committed”的方法包括: 1. **检查和修正逻辑**:确保在请求处理的任何阶段,一旦响应被提交,就不再进行转发或重定向。 2. **使用try-catch-finally**:在可能抛出...
`response.getOutputStream()` 方法是Servlet API的一部分,它用于获取与HTTP响应关联的输出流对象。这个方法在服务器端处理请求时非常常见,尤其在构建动态网页时。 当我们处理一个HTTP请求时,服务器会创建一个`...
2. 转发:`RequestDispatcher`的`forward(ServletRequest request, ServletResponse response)`方法可以在服务器端将请求转发到另一个资源。这不会改变客户端的URL。 ```java RequestDispatcher dispatcher = ...
HttpServletRequest-response方法总结 HttpServletRequest和HttpServletResponse是Servlet编程中两个最重要的接口,它们提供了对HTTP请求和响应的控制和处理。下面是对HttpServletRequest和HttpServletResponse的...
标题 "java.lang.IllegalStateException: OutputStream already obtain" 涉及到的是Java编程中的一个常见错误,特别是当处理I/O流时。这个异常通常在尝试获取已经存在的OutputStream实例时抛出,表明该输出流已经被...
### Java Response 下载文件方法详解 在Web应用开发过程中,经常需要实现文件的上传与下载功能。其中,通过`java response`实现文件下载是常见需求之一。本文将深入解析如何利用Java中的`HttpServletResponse`对象...
3. `getOutputStream()`:返回ServletOutputStream,用于写入二进制数据到响应体,如文件下载。 4. `getWriter()`:返回PrintWriter,用于写入文本数据到响应体,如HTML、JSON等。 在实际应用中,我们通常会创建一...
3. 使用`FileInputStream`读取文件内容,并通过`response.getOutputStream().write()`将内容写入响应流。 通过以上方法,我们可以在处理中文文件名的文件下载时,有效避免乱码问题,确保用户能够正确下载并识别文件...
### Response-Headers详解 #### HTTP响应报头的基本概念与作用 HTTP响应报头是Web服务器向客户端(通常是浏览器)发送响应时附带的信息。这些报头提供了关于响应本身的元数据,如响应的内容类型、长度等,对于正确...
3. 将验证码图片输出到客户端,使用ServletResponse对象的getOutputStream()方法。 4. 将验证码存入Session中,以便后续验证。 知识点3: 验证码图片不显示的问题 在本例中,验证码图片生成成功,但是却不显示在...
Returns a boolean indicating whether the named response header has already been set. contextDestroyed(ServletContextEvent) - Method in interface javax.servlet.ServletContextListener Notification ...
在本文档中,我们将详细介绍request和response对象的功能和使用方法。 request对象 request对象是JSP内置对象中的一员,它用于处理客户端请求信息。在Servlet.service方法中,request对象作为参数传入,以便...
1. 解决方法一:`response.setCharacterEncoding("UTF-8")`用于设置响应体的字符编码,解决`response.getWriter()`输出的乱码问题。 2. 解决方法二:`response.setHeader("Content-Type", "text/html;charset=UTF-8...
通过`getOutputStream()`或`getWriter()`方法,我们可以获取到用于写入响应体的流。前者适用于二进制数据,后者适用于文本数据。 8. **响应缓冲区** 默认情况下,响应会被缓冲,直到缓冲区满或者调用`flushBuffer...