首页  >  问答  >  正文

在 JSP 页面中从数据库检索和显示图像:分步指南

<p>如何在 JSP 页面中检索和显示数据库中的图像?</p>
P粉191610580P粉191610580419 天前651

全部回复(1)我来回复

  • P粉251903163

    P粉2519031632023-08-28 18:47:50

    让我们分步骤看看会发生什么:

    • 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()< /a> 为此,JPA API 提供@Lob 为此。
    • 在 Servlet 中,您只需将此 byte[]InputStream 写入响应的 OutputStream(通常的 Java IO 方式。
    • 需要指示客户端将数据作为图像处理,因此至少Content-Type 响应头也需要设置。您可以通过 ServletContext#getMimeType() 基于图像文件扩展名,您可以通过 web.xml 中的 扩展和/或覆盖该扩展名

    应该是这样。它几乎自己编写代码。让我们从 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">
    

    如果需要,您还可以在使用 EL 动态设置 src ="https://stackoverflow.com/tags/jstl/info">JSTL:

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

    然后定义/创建一个servlet,它侦听 /images/*< URL 模式上的 GET 请求/code>,下面的示例使用普通的 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);
            }
        }
    
    }

    就是这样。如果您担心 HEAD 和缓存标头并正确响应这些请求,请使用此 静态资源servlet的抽象模板

    另请参阅:

    回复
    0
  • 取消回复