You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Lyallex <ly...@gmail.com> on 2007/07/03 11:36:09 UTC

Images and response.getOutputStream()

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)

Re: Images and response.getOutputStream()

Posted by Lyallex <ly...@gmail.com>.
Ricardo

What can I say ... sometimes you just get a mental block about these things

I used a servlet and now I don't get any
java.lang.IllegalStateExceptions when loading images

Thank you for showing me the light.

Regards
Duncan

On 7/3/07, rpr_listas <rp...@telefonica.net> wrote:
>
> Hi Lyallex!
> You're getting a OutputStream ftrom a JSP? If the JSP has a simple
> single empty line before your java code <%%>, the JSP framework  get a
> writer before your java code is executred. This is the cause of the
> IllegalState Exception. The rigth way to do this is from a servlet, but
> if you prefer still using JSP, clean any empty space before your java
> code.
>
> This code probably fails:
>
>    <%@page import ..>
>    <%@page ... >
>
>    <%
>    //my java code
>    %>
>
>    EOF
>
> An this avoid the problem:
>
>    <%page ....><%
>    //my java code
>    //other java line
>    %>EOF
>
> Best regards.
> Ricardo
>
> Lyallex escribió:
> > 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)
> >
>
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>

Re: Images and response.getOutputStream()

Posted by rpr_listas <rp...@telefonica.net>.
Hi Lyallex!
You're getting a OutputStream ftrom a JSP? If the JSP has a simple 
single empty line before your java code <%%>, the JSP framework  get a 
writer before your java code is executred. This is the cause of the 
IllegalState Exception. The rigth way to do this is from a servlet, but 
if you prefer still using JSP, clean any empty space before your java code.

This code probably fails:

   <%@page import ..>
   <%@page ... >
  
   <%
   //my java code
   %>
  
   EOF

An this avoid the problem:

   <%page ....><%
   //my java code
   //other java line
   %>EOF

Best regards.
Ricardo

Lyallex escribió:
> 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)
>


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org