我有一个jsp,其中对于表的每一行,我需要显示数据库中存在的图像。我从数据库中检索所有表行数据,包括作为Blob的图像,并将其存储在bean中。图像作为字节数组存储在bean中,如下所示:
photo = rs.getBlob("PHOTO");
photoByteArray = photo.getBytes(1, (int)photo.length());
在jsp中遍历bean列表时,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;
}
}
}
假设您可以将随机二进制数据放入HTML文件中,并且它将被正确解析,并完整地发送回服务器。这是一个糟糕的假设!不出意外的话,对应于引号字符ASCII码的字节就会产生问题,对吧?更不用说编码问题,以及URL的参数必须被unlencoded这一事实。这是注定要失败的。
要做到这一点,必须在提供页面时对二进制数据进行某种显式的文本编码(可能是base64),然后在URL返回后将servlet参数解码回二进制图像数据。
您的第一个processRequest()代码段只发送回photoData请求参数的字节表示形式,而不是参数标识的照片数据。看起来你的代码有bug
看来你试图用错误的方式来解决你的问题。当您第一次创建HTML表时,将来自第一次查询的图像存储在"bean"中不会得到任何东西,除非您缓存数据,并且随后的displayThumbnail请求从缓存中检索图像,从而避免了数据库查询。如果您不想弄乱缓存,那么就没有必要将图像存储在初始bean中,因为它没有给您任何东西,只需执行类似于第二个processRequest()代码片段的操作,以便在浏览器请求时直接获取图像。
您的${part.photoData}
表达式必须返回某个ID。在processRequest()方法中,您必须获得该ID值(通过使用request.getParameter("photoData")),并通过该值从数据库(或更好地从缓存或文件系统)检索图像,并将二进制数据发送到web客户端。