Java 如何在 JSP 页面中从数据库中检索和显示图像?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2340406/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to retrieve and display images from a database in a JSP page?
提问by krunal
How can I retrieve and display images from a database in a JSP page?
如何在 JSP 页面中从数据库中检索和显示图像?
回答by ewernli
I suggest you address that as two problems. There are several questions and answer related to both.
我建议您将其视为两个问题。有几个问题和答案与两者相关。
How to load blob from MySQL
See for instance Retrieve image stored as blob
How to display image dynamically
See for instance Show thumbnail dynamically
如何从 MySQL 加载 blob
参见例如检索存储为 blob 的图像
如何动态显示图像
参见例如动态显示缩略图
回答by BalusC
Let's see in steps what should happen:
让我们分步骤看看会发生什么:
- JSP is basically a view technology which is supposed to generate HTML output.
- To display an image in HTML, you need the HTML
<img>
element. - To let it locate an image, you need to specify its
src
attribute. - The
src
attribute needs to point to a validhttp://
URL and thus not a local disk file system pathfile://
as that would never work when the server and client run at physically different machines. - The image URL needs to have the image identifier in either the request path (e.g.
http://example.com/context/images/foo.png
) or as request parameter (e.g.http://example.com/context/images?id=1
). - In JSP/Servlet world, you can let a Servlet listen on a certain URL pattern like
/images/*
, so that you can just execute some Java code on specific URL's. - Images are binary data and are to be obtained as either a
byte[]
orInputStream
from the DB, the JDBC APIoffers theResultSet#getBytes()
andResultSet#getBinaryStream()
for this, and JPA APIoffers@Lob
for this. - In the Servlet you can just write this
byte[]
orInputStream
to theOutputStream
of the response the usual Java IOway. - The client side needs to be instructed that the data should be handled as an image, thus at least the
Content-Type
response header needs to be set as well. You can obtain the right one viaServletContext#getMimeType()
based on image file extension which you can extend and/or override via<mime-mapping>
inweb.xml
.
- JSP 基本上是一种视图技术,它应该生成 HTML 输出。
- 要以 HTML 格式显示图像,您需要 HTML
<img>
元素。 - 要让它定位图像,您需要指定其
src
属性。 - 该
src
属性需要指向有效的http://
URL,因此不是本地磁盘文件系统路径file://
,因为当服务器和客户端在物理上不同的机器上运行时,这将永远无法工作。 - 图像 URL 需要在请求路径(例如
http://example.com/context/images/foo.png
)或作为请求参数(例如http://example.com/context/images?id=1
)中具有图像标识符。 - 在 JSP/Servlet 世界中,您可以让 Servlet 侦听某个 URL 模式,例如
/images/*
,以便您可以在特定 URL 上执行一些 Java 代码。 - 图像是二进制数据并且将被无论是作为获得
byte[]
或InputStream
从DB中,JDBC API提供ResultSet#getBytes()
与ResultSet#getBinaryStream()
此,和JPA API提供@Lob
用于此。 - 在Servlet中,你可以只写这个
byte[]
或者InputStream
到OutputStream
响应的常用的Java IO方式。 - 需要指示客户端将数据作为图像处理,因此至少还
Content-Type
需要设置响应头。您可以通过ServletContext#getMimeType()
基于图像文件扩展名的方式获取正确的方式,您可以通过<mime-mapping>
in扩展和/或覆盖该扩展名web.xml
。
That should be it. It almost writes code itself. Let's start with HTML (in JSP):
应该是这样。它几乎自己编写代码。让我们从 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">
You can if necessary also dynamically set src
with ELwhile iterating using JSTL:
<c:forEach items="${imagenames}" var="imagename">
<img src="${pageContext.request.contextPath}/images/${imagename}">
</c:forEach>
Then define/create a servletwhich listens on GET requests on URL pattern of /images/*
, the below example uses plain vanilla JDBC for the job:
然后定义/创建一个servlet,它侦听 URL 模式上的 GET 请求/images/*
,下面的示例使用普通的 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);
}
}
}
That's it. In case you worry about HEAD and caching headers and properly responding on those requests, use this abstract template for static resource servlet.
就是这样。如果您担心 HEAD 和缓存标头并正确响应这些请求,请将此抽象模板用于静态资源 servlet。
See also:
也可以看看:
回答by Musaddique
You can also create custom tag for displaying image.
您还可以创建用于显示图像的自定义标签。
1) create custom tag java class and tld file.
1)创建自定义标签java类和tld文件。
2) write logic to display image like conversion of byte[] to string by Base64.
2) 编写逻辑来显示图像,例如通过 Base64 将 byte[] 转换为字符串。
so it is used for every image whether you are displaying only one image or multiple images in single jsp page.
因此,无论您是在单个 jsp 页面中仅显示一张图像还是多张图像,它都会用于每个图像。
回答by Gaurav Mahindra
I used SQL SERVER database and so the answer's code is in accordance. All you have to do is include an <img>
tag in your jsp page and call a servlet from its src attribute like this
我使用了 SQL SERVER 数据库,所以答案的代码是一致的。你所要做的就是<img>
在你的 jsp 页面中包含一个标签,并像这样从它的 src 属性调用一个 servlet
<img width="200" height="180" src="DisplayImage?ID=1">
Here 1 is unique id of image in database and ID is a variable. We receive value of this variable in servlet. In servlet code we take the binary stream input from correct column in table. That is your image is stored in which column. In my code I used third column because my images are stored as binary data in third column. After retrieving input stream data from table we read its content in an output stream so it can be written on screen. Here is it
这里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());
}
}
}
}
After the execution of your jsp or html file you will see the image on screen.
在执行您的 jsp 或 html 文件后,您将在屏幕上看到图像。
回答by Sonam Tshering
Try to flush and close the output stream if it does not display.
Blob image = rs.getBlob(ImageColName);
InputStream in = image.getBinaryStream();
// Output the blob to the HttpServletResponse
response.setContentType("image/jpeg");
BufferedOutputStream o = new BufferedOutputStream(response.getOutputStream());
如果未显示,请尝试刷新并关闭输出流。
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();