2011-04-22 66 views
0

我有一个jsp其中表中的每一行我需要显示数据库中存在的图像。我从数据库中检索所有表格行数据,包括图像作为Blob,并将其存储在一个bean中。该图像被存储在bean作为字节数组这样的:图像没有送达jsp从Servlets

photo = rs.getBlob("PHOTO"); 
photoByteArray = photo.getBytes(1, (int)photo.length()); 

虽然循环遍历JSP豆的列表中,在src属性指向这样一个servlet:

<img class="img" width="55" height="50" src="displayThumbnail?photoData=${part.photoData}"> 

供应的图像如下所示,但是它们不显示,但是在调试字节数组时似乎有数据。

protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws IOException { 
    response.setContentType("image/jpeg"); 
    OutputStream o = response.getOutputStream(); 
    String photoDataStr = request.getParameter("photoData"); 
    byte[] photoData = null; 
    if(photoDataStr != null) { 
     photoData = photoDataStr.getBytes(); 
    } 
    o.write(photoData); 
    o.close(); 
} 

但是图像没有显示出来。现在,如果我如下所示查询每个单独图像的数据库,那么在这种情况下图像确实显示得很好。

protected void processRequest(HttpServletRequest request, HttpServletResponse response) { 
    PreparedStatement pstmt = null; 
    ResultSet rs = null; 
    Connection conn = null; 
      try { 
     if(conn == null) { 
      conn = open(); 
     } 
     pstmt = conn.prepareStatement("select photo from PART_PHOTOS where id = ?"); 
     String id = request.getParameter("id"); 
     pstmt.setString(1, id); 
     rs = pstmt.executeQuery(); 
     if (rs.next()) { 
      Blob b = rs.getBlob("photo"); 
      response.setContentType("image/jpeg"); 
      response.setContentLength((int) b.length()); 
      InputStream is = b.getBinaryStream(); 
      OutputStream os = response.getOutputStream(); 
      byte buf[] = new byte[(int) b.length()]; 
      is.read(buf); 
      os.write(buf); 
      os.close(); 
      is.close(); 
     } 
    } catch (Exception ex) { 
     System.out.println(ex.getMessage()); 
     ex.printStackTrace(); 
    } finally { 
     if (rs != null) { 
      try { 
       rs.close(); 
      } catch (SQLException e) { 
       e.printStackTrace(); 
      } 
      rs = null; 
     } 
     if (pstmt != null) { 
      try { 
       pstmt.close(); 
      } catch (SQLException e) { 
       e.printStackTrace(); 
      } 
      pstmt = null; 
     } 
     //check if it's the end of the loop 
      if (conn != null) { 
        try { 
         conn.close(); 
        } catch (SQLException e) { 
         e.printStackTrace(); 
        } 
        conn = null; 
       } 
    } 
} 

我非常感谢,如果任何人都可以提供任何相同的建议。

回答

0

假设您可以将随机二进制数据放入一个HTML文件中,并且它将被正确解析并完整地发送回到您的服务器。这是一个糟糕的假设!如果没有别的,与引用字符的ASCII对应的字节会导致问题,对吧?更不用说编码问题了,以及URL的参数必须被urlencoded。这只是注定要失败。

为了完成这项工作,当您提供页面(base64,也许)时,必须对二进制数据进行某种明确的文本编码,然后在URL之后将servlet参数解码为二进制图像数据被回发。

+0

@BaluC:有没有什么快速的方法不需要花费太多的时间来设置缓存等等。 – 2011-04-22 16:24:40

+1

@BalusC:现在你应该可以从OP留下的一些其他评论中看到,他的确是,试图将图像数据直接粘贴到HTML:quote中,“$ {part.photoData}返回从初始数据库调用中检索到的字节数组”。然后他希望他的servlet能够从嵌入它的地方提取该字节数组作为标记中的URL,并将其直接返回给请求者。我认为我对我的解释非常清楚,但其他答复似乎都没有意识到发生了什么。 – 2011-04-22 17:21:59

+0

哦,他试图通过整个图像作为参数!对不起,我现在看到了。我将它解释为图像标识符。我回我的话。 – BalusC 2011-04-22 17:28:50

0

您的第一个processRequest()代码片段仅返回photoData请求参数的字节表示而不是参数标识的照片数据。看起来像你的代码中的错误。

看来你试图以错误的方式解决你的问题。当你第一次创建HTML表格时,从第一个查询中将图像存储在“bean”中将不会为你提供任何信息,除非你缓存数据,而后续的displayThumbnail请求从缓存中检索图像,避免数据库查询。

如果你不想混淆高速缓存,那么就不需要将图像存储在你的初始bean中,因为它没有给你任何东西,只需要做一些事情,比如你的第二个processRequest()片段直接获取图像浏览器要求它。

0

您的${part.photoData}表达式必须返回一些ID。在processRequest()方法中,您必须获取该ID值(通过使用request.getParameter(“photoData”))并通过该值从数据库中检索图像(或者从缓存或文件系统中更好地获取)并将二进制数据发送到Web客户机。

+0

$ {part.photoData}返回从初始数据库调用中检索到的字节数组。我不想为检索图像进行单独的数据库调用。 – 2011-04-22 16:21:14

+1

你不能将字节数组放入img标签的src属性,它不会工作。 如果你不想调用数据库,你可以保存ID为key和byte数组为值的map。 – user179437 2011-04-22 16:40:01