【发布时间】:2015-02-28 06:13:39
【问题描述】:
如何在 JSP 页面中从数据库中检索和显示图像?
【问题讨论】:
如何在 JSP 页面中从数据库中检索和显示图像?
【问题讨论】:
如果没有显示,请尝试刷新并关闭输出流。
Blob image = rs.getBlob(ImageColName);
InputStream in = image.getBinaryStream();
// 将 blob 输出到 HttpServletResponse
response.setContentType("image/jpeg");
BufferedOutputStream o = new BufferedOutputStream(response.getOutputStream());
byte by[] = new byte[32768];
int index = in.read(by, 0, 32768);
while (index != -1) {
o.write(by, 0, index);
index = in.read(by, 0, 32768);
}
o.flush();
o.close();
【讨论】:
我使用的是 SQL SERVER 数据库,所以答案的代码是一致的。你所要做的就是在你的jsp页面中包含一个<img>标签,然后像这样从它的src属性调用一个servlet
<img width="200" height="180" src="DisplayImage?ID=1">
这里 1 是图像在数据库中的唯一 ID,ID 是一个变量。我们在 servlet 中接收这个变量的值。在 servlet 代码中,我们从表中的正确列获取二进制流输入。那就是你的图像存储在哪一列。在我的代码中,我使用了第三列,因为我的图像作为二进制数据存储在第三列中。从表中检索输入流数据后,我们在输出流中读取其内容,以便将其写入屏幕。在这里
import java.io.*;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.*;
import javax.servlet.http.*;
import model.ConnectionManager;
public class DisplayImage extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse response)
throws IOException
{
Statement stmt=null;
String sql=null;
BufferedInputStream bin=null;
BufferedOutputStream bout=null;
InputStream in =null;
response.setContentType("image/jpeg");
ServletOutputStream out;
out = response.getOutputStream();
Connection conn = ConnectionManager.getConnection();
int ID = Integer.parseInt(request.getParameter("ID"));
try {
stmt = conn.createStatement();
sql = "SELECT * FROM IMAGETABLE WHERE ID="+ID+"";
ResultSet result = stmt.executeQuery(sql);
if(result.next()){
in=result.getBinaryStream(3);//Since my data was in third column of table.
}
bin = new BufferedInputStream(in);
bout = new BufferedOutputStream(out);
int ch=0;
while((ch=bin.read())!=-1)
{
bout.write(ch);
}
} catch (SQLException ex) {
Logger.getLogger(DisplayImage.class.getName()).log(Level.SEVERE, null, ex);
}finally{
try{
if(bin!=null)bin.close();
if(in!=null)in.close();
if(bout!=null)bout.close();
if(out!=null)out.close();
if(conn!=null)conn.close();
}catch(IOException | SQLException ex){
System.out.println("Error : "+ex.getMessage());
}
}
}
}
在你的jsp或html文件执行后,你会在屏幕上看到图片。
【讨论】:
让我们分步看看会发生什么:
<img> 元素。src 属性。src 属性需要指向有效的http:// URL,因此不能指向本地磁盘文件系统路径file://,因为当服务器和客户端在物理上不同的机器上运行时,这将永远无法工作。http://example.com/context/images/foo.png)或作为请求参数(例如 http://example.com/context/images?id=1)。/images/*,这样您就可以在特定的 URL 上执行一些 Java 代码。byte[] 或InputStream 从数据库中获取,JDBC API 为此提供ResultSet#getBytes() 和ResultSet#getBinaryStream(),JPA API 提供@Lob为此。byte[] 或 InputStream 写入响应的 OutputStream。Content-Type响应头。您可以根据图像文件扩展名通过ServletContext#getMimeType() 获取正确的图像文件扩展名,您可以通过web.xml 中的<mime-mapping> 扩展和/或覆盖。应该是这样的。它几乎自己编写代码。让我们从 HTML 开始(JSP):
<img src="${pageContext.request.contextPath}/images/foo.png">
<img src="${pageContext.request.contextPath}/images/bar.png">
<img src="${pageContext.request.contextPath}/images/baz.png">
如果需要,您还可以在使用 JSTL 进行迭代时动态设置 src 和 EL:
<c:forEach items="${imagenames}" var="imagename">
<img src="${pageContext.request.contextPath}/images/${imagename}">
</c:forEach>
然后定义/创建一个servlet,它在/images/* 的 URL 模式上侦听 GET 请求,下面的示例使用普通的 JDBC 来完成这项工作:
@WebServlet("/images/*")
public class ImageServlet extends HttpServlet {
// content=blob, name=varchar(255) UNIQUE.
private static final String SQL_FIND = "SELECT content FROM Image WHERE name = ?";
@Resource(name="jdbc/yourDB") // For Tomcat, define as <Resource> in context.xml and declare as <resource-ref> in web.xml.
private DataSource dataSource;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String imageName = request.getPathInfo().substring(1); // Returns "foo.png".
try (Connection connection = dataSource.getConnection(); PreparedStatement statement = connection.prepareStatement(SQL_FIND)) {
statement.setString(1, imageName);
try (ResultSet resultSet = statement.executeQuery()) {
if (resultSet.next()) {
byte[] content = resultSet.getBytes("content");
response.setContentType(getServletContext().getMimeType(imageName));
response.setContentLength(content.length);
response.getOutputStream().write(content);
} else {
response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
}
}
} catch (SQLException e) {
throw new ServletException("Something failed at SQL/DB level.", e);
}
}
}
就是这样。如果您担心 HEAD 和缓存标头并正确响应这些请求,请使用此 abstract template for static resource servlet。
【讨论】:
您还可以创建自定义标签来显示图像。
1) 创建自定义标签java类和tld文件。
2) 编写逻辑以显示图像,例如通过 Base64 将 byte[] 转换为字符串。
因此,无论您是在单个 jsp 页面中仅显示一张图片还是多张图片,它都适用于每张图片。
【讨论】:
我建议您将其作为两个问题来解决。有几个与两者相关的问题和答案。
如何从 MySQL 加载 blob
如何动态显示图片
【讨论】: