His Janusz,

I think the problem is that you store your connection in your session.
Alle threads are sharing the same session object, and are therefore using
the same connection object.
Subsequent access (within the same session) to your ImageAction will
probably succeed, but concurrent access will fail.
As you said, your application gets only few request, so I think that is why
the problem did not occur before. (Concurrent requests in the same session
will have the same problem)

I guess you want to 'cache' your connection to avoid the overhead of
creating and openening a connection every time.
You should really use a different mechanism to achieve this.
Take a look at DBCP (database connection pooling), one of the
jakarta-commons components (http://jakarta.apache.org/commons/dbcp/).

There is one other thing that can go wrong in your code:
You call response.setContentLength(len); after you've written the complete
image to your OutputStream.
The call to response.setContentLength(len); attempts to send a HTTP header
value. If the the response was already flushed to the client, this header
will never be sent.
The same remark is valid for response.setContentType("image/jpeg");
I suggest you to call response.setContentType("image/jpeg"); before you
stream the binary image.
Since you know the size of the retrieved image only after you've read the
binary stream, you cannot call response.setContentLength(len) earlier. 
An alternative might be (if your driver supports it):
java.sql.Blob blob = rs.getBlob(1);
len = blob.length();
response.setContentLength(len);
InputStream is = blob.getBinaryStream();
etc.

Good luck,

Remke 

> -----Oorspronkelijk bericht-----
> Van: Janusz Dziadon [mailto:[EMAIL PROTECTED]
> Verzonden: dinsdag 16 december 2003 0:37
> Aan: [EMAIL PROTECTED]
> Onderwerp: Getting images from Interbase database
> 
> 
> Hi all!
> 
> I am using Struts from about half a year, and it works good. 
> I have small
> webapp using Interbase database by Interclient driver.
> When I wanted to use only text data from queries all was fine 
> and simply,
> even when "single" jpegs from blob fields. But now I must display some
> images on one page and I have some errors with doing that.
> 
> My action classes do their work in "normal" way - using 
> database connection
> they get data by ResultSets, transfer them to my java beans, 
> and jsp page is
> responsible for formatting and displaying this data. But, 
> like I've told it
> is related only to text data. All pages till now displayed no 
> more than one
> image from database. To achieve that, on required jsp pages is placed
> <html:img> tag with proper properties (ie. image id) which is 
> linked to
> special action (ImageAction) descendant properly configured 
> in "struts.xml"
> file. His work is to:
> - extract parameters from request (imageid=87)
> - get one-row ResultSet (rs) with image (select image from 
> images where
> imageid=87)
> - gets this image by rs.getBinaryStream(1)
> - copy this stream to ServletOutputStream
> - set response mime type and len
> - send response by closing its output stream
> (code of this class is attached below)
> When I need one image on browser page then jsp page contains one tag
> <html:img page="/smallImage.do?imageid=87" />. And all works FINE.
> SmallImage action simply calls ImageAction. Requests from 
> users goes to
> server not often.
> 
> But now I need display html-table with five images and this 
> technique not
> work. Jsp page contains
> <table>
>   <tr>
>     <td><html:img page="/smallImage.do?imageid=87" /></td>
>     <td><html:img page="/smallImage.do?imageid=88" /></td>
>   </tr>
>   <tr>
>     <td><html:img page="/smallImage.do?imageid=89" /></td>
>     <td><html:img page="/smallImage.do?imageid=90" /></td>
>  </tr>
> </table>
> As you see one big change to previous page is that 
> ActionImage class is
> called four times to fill one page, and this request goes to 
> server almost
> at once.
> 
> Errors suggest me, that responsible for this situation goes 
> from ImageAction
> to Interclient, but I'm not sure. Generally most frequently I 
> get no images,
> sometimes only one image, but never all four required. All images in
> database table are in good format, because when I want to get 
> only one image
> on page they are displayed correctly.
> 
> So I've started my investigation on "How ImageAction doesn't work
> correctly". I've put into ImageAction class some additional 
> code to write
> out whats going on. I must say that it looks like action gets 
> four request,
> starts "simultaneously" create statements, and gets 
> ResultSets. Problems is
> when its starts to copy "blob" stream (place is marked in code).
> I've get "JDBC IOException: Invalid operation to read on 
> closed blob stream.
> See API reference for exception 
> interbase.interclient.BlobIOEception". All
> subsequent tries to copy ends with error "[interclient] Client/server
> protocol error: Unexpected token in network message received from
> Interserver. The internal code is 101. See Api reference for exception
> interbase.interclient.RemoteProtocolException". Connection to 
> database is
> broken.
> 
> QUESTIONS:
> 1. Is it possible that Interclient driver doesn't support Blobs in
> multithread way?
> 2. Should I change the database engine?
> 3. Or should I make some trick to collect only one image at a 
> time ? How can
> I achieve that ?
> 4. Or what am I doing wrong? Maybe not synchronizing but I 
> dont understand
> this very well.
> 5. Can anybody help me at all?
> 
> 
> My configuration
> Tomcat 4.0, Interbase 6.0.1.6 (Open Source)
> 
> 
> My code for ImageAction
> package jd.struts.images;
> 
> import org.apache.struts.action.*;
> import javax.servlet.http.*;
> import javax.servlet.*;
> import java.io.*;
> import java.sql.*;
> 
> public class ImageAction extends Action {
>   public ActionForward perform(ActionMapping mapping, ActionForm form,
> HttpServletRequest request, HttpServletResponse response) {
>     String sParam = request.getParameter("imageid");
>     try{
>       Integer iParam = new Integer(sParam);
>       int i = iParam.intValue();
>       if (i>0){
>         HttpSession session=request.getSession();
>         Connection connection =
> (Connection)session.getAttribute("connection");
>         if (connection!=null){
>           try {
>             Statement st = connection.createStatement();
>             ServletOutputStream sos = 
> httpServletResponse.getOutputStream();
>             ResultSet rs = st.executeQuery("select image from 
> umowyimages
> where umimageid=" + i);
>             if (rs.next()) {
>               InputStream is = rs.getBinaryStream(1);
>               int len = is.available();
> <--- here gives back correct blob size
>               byte b[] = new byte[12];
>               while (true) {
>                 int bytes = is.read(b);
> <--- here appears first error
>                 if (bytes == -1) {
>                   break;
>                 }
>                 else {
>                   len += bytes;
>                 }
>                 sos.write(b, 0, bytes);
>               }
>             }
>             rs.close();
>             st.close();
>             response.setContentType("image/jpeg");
>             response.setContentLength(len);sos.close();
>           }
>           catch (Exception ex) {
>             System.out.println(toString()+"sqlError: 
> "+ex.getMessage());
>           }
>         }
>         else{
>           System.out.println(toString()+" connectionError");
>         }
>       }
>       else{
>         System.out.println(toString()+" paramError");
>       }
>     }
>     catch (NumberFormatException nfe) {
>       System.out.println(toString()+" conversionError");
>     }
>     return null;
>   }
> }
> 
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to