如何在 JSP 页面中从数据库中检索和显示图像? [英] How to retrieve and display images from a database in a JSP page?

查看:22
本文介绍了如何在 JSP 页面中从数据库中检索和显示图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在 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 valid http:// URL and thus not a local disk file system path file:// 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[] or InputStream from the DB, the JDBC API offers the ResultSet#getBytes() and ResultSet#getBinaryStream() for this, and JPA API offers @Lob for this.
  • In the Servlet you can just write this byte[] or InputStream to the OutputStream 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 via ServletContext#getMimeType() based on image file extension which you can extend and/or override via <mime-mapping> in web.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆