Hi I'm not sure this is a Tomcat question, more likely a poor understanding of the Request/Response lifecycle on my part but I'll give it a go anyway.
After agonising for days(weeks) over whether to store my images in a database or on the filesystem I opted for the database. I have everything working fine ... apart from one little niggling thing that I just cannot figure out. Every time I get an image from the database I get an exception java.lang.IllegalStateException: getOutputStream() has already been called for this response ... Now I think I understand why this is happening, I read somewhere that you cannot get a JspWriter (via a call to the implicit object out for example) and a binary output stream (ServletOutputStream outStream = response.getOutputStream ()) from the same response. Nothing falls over and the images appear fine. It's really the exception traces I'm trying to get rid of It appears that others are also using a database to store images and have things working. (mainly from http://marc.info/?l=tomcat-user) Can anyone advise me as to how to write both text and image data out to the same response without this exception clogging up all my log files ? I have included code below if you want/need to read it Many thanks Duncan //============== get an image in a jsp ============= //where p is a Product Object that contains information on the image name as stored in the database //images can be thumbnails or normal size <img src="imageproxy.jsp?imageid=<%=p.calculateImageId()%>&imagetype=thumb" width='80'> //============== imageproxy.jsp ================ //where ImageServer is a singleton that gets an InputStream on a MySQL database BLOB boolean DEBUG = false; ServletOutputStream outStream = response.getOutputStream(); response.reset(); response.setHeader("Expires", "-1"); response.setHeader("Cache-Control", "no-cache"); String imageId = request.getParameter (imageid); String imageType = request.getParameter(imagetype); ImageServer images = ImageServer.getServer(); InputStream inStream = images.getImageData(imageId, imageType); if(DEBUG){ System.out.println("imageproxy.jsp, inStream has " + inStream.available() + " bytes available"); } byte[] bytes = new byte[1000]; int bytesRead = inStream.read(bytes); while (bytesRead != -1) { outStream.write(bytes,0,bytesRead); bytesRead = inStream.read(bytes); } outStream.flush (); inStream.close(); //============= Just FYI here is the trace (one per image) ============= SEVERE: Servlet.service() for servlet jsp threw exception java.lang.IllegalStateException: getOutputStream() has already been called for this response at org.apache.catalina.connector.Response.getWriter(Response.java :599) at org.apache.catalina.connector.ResponseFacade.getWriter( ResponseFacade.java:195) at org.apache.jasper.runtime.JspWriterImpl.initOut ( JspWriterImpl.java:124) at org.apache.jasper.runtime.JspWriterImpl.flushBuffer( JspWriterImpl.java:117) at org.apache.jasper.runtime.PageContextImpl.release( PageContextImpl.java:191) at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext ( JspFactoryImpl.java:115) at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext( JspFactoryImpl.java:75) at org.apache.jsp.imageproxy_jsp._jspService(imageproxy_jsp.java:94) at org.apache.jasper.runtime.HttpJspBase.service (HttpJspBase.java :97) at javax.servlet.http.HttpServlet.service(HttpServlet.java:802) at org.apache.jasper.servlet.JspServletWrapper.service( JspServletWrapper.java:332) at org.apache.jasper.servlet.JspServlet.serviceJspFile ( JspServlet.java:314) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264) at javax.servlet.http.HttpServlet.service(HttpServlet.java:802) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter( ApplicationFilterChain.java:252) at org.apache.catalina.core.ApplicationFilterChain.doFilter( ApplicationFilterChain.java:173) at org.apache.catalina.core.StandardWrapperValve.invoke( StandardWrapperValve.java :213) at org.apache.catalina.core.StandardContextValve.invoke( StandardContextValve.java:178) at org.apache.catalina.authenticator.AuthenticatorBase.invoke( AuthenticatorBase.java:432) at org.apache.catalina.core.StandardHostValve.invoke ( StandardHostValve.java:126) at org.apache.catalina.valves.ErrorReportValve.invoke( ErrorReportValve.java:105) at org.apache.catalina.core.StandardEngineValve.invoke( StandardEngineValve.java:107) at org.apache.catalina.connector.CoyoteAdapter.service( CoyoteAdapter.java:148) at org.apache.coyote.http11.Http11Processor.process( Http11Processor.java:869) at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection( Http11BaseProtocol.java:664) at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket( PoolTcpEndpoint.java:527) at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt( LeaderFollowerWorkerThread.java :80) at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run( ThreadPool.java:684) at java.lang.Thread.run(Thread.java:595)