如何在 JSP 页面中从数据库中检索和显示图像? [英] How to retrieve and display images from a database in a JSP page?
问题描述
如何在 JSP 页面中从数据库中检索和显示图像?
How can I retrieve and display images from a database in a JSP page?
推荐答案
让我们分步骤看看会发生什么:
Let's see in steps what should happen:
- JSP 基本上是一种视图技术,应该生成 HTML 输出.
- 要以 HTML 格式显示图像,您需要 HTML
元素.
- 要让它定位图像,您需要指定其
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
的形式获取,JDBC API 提供了ResultSet#getBytes()
和ResultSet#getBinaryStream()
为此,JPA API 提供了@Lob
为此.莉> - 在 Servlet 中,您可以将这个
byte[]
或InputStream
写入响应的OutputStream
中,通常的 Java IO 方式. - 需要指示客户端将数据作为图像处理,因此至少
Content-Type
响应头也需要设置.您可以通过ServletContext#getMimeType()
基于图像文件扩展名,您可以通过
在web.xml
.
- 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 API offers theResultSet#getBytes()
andResultSet#getBinaryStream()
for this, and JPA API offers@Lob
for this. - In the Servlet you can just write this
byte[]
orInputStream
to theOutputStream
of the response the usual Java IO way. - 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
.
应该是这样.它几乎自己编写代码.让我们从 HTML 开始(在 JSP 中):
That should be it. It almost writes code itself. Let's start with HTML (in 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">
如有必要,您还可以在使用 EL 动态设置 src
="https://stackoverflow.com/tags/jstl/info">JSTL:
You can if necessary also dynamically set src
with EL while iterating using JSTL:
<c:forEach items="${imagenames}" var="imagename">
<img src="${pageContext.request.contextPath}/images/${imagename}">
</c:forEach>
然后定义/创建一个 servlet,它监听 /images/*<的 URL 模式的 GET 请求/code>,下面的例子使用普通的 JDBC 来完成这项工作:
Then define/create a servlet which listens on GET requests on URL pattern of /images/*
, the below example uses plain vanilla JDBC for the job:
@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 和缓存标头并正确响应这些请求,请使用此 静态资源servlet的抽象模板.
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.
这篇关于如何在 JSP 页面中从数据库中检索和显示图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!