如何从JSP页面中的数据库中检索和显示图像?

kru*_*nal 26 java jsp servlets image

如何从JSP页面中的数据库中检索和显示图像?

Bal*_*usC 66

让我们看看应该发生什么:

  • 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[]或者InputStreamOutputStream响应的常用的Java IO方式.
  • 需要指示客户端数据应作为图像处理,因此至少Content-Type需要设置响应头.通过您可以获得正确的ServletContext#getMimeType()基于图像文件的扩展,你可以扩展和/或通过覆盖<mime-mapping>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">
Run Code Online (Sandbox Code Playgroud)

必要时,可以动态地也设置srcEL而使用迭代JSTL:

<c:forEach items="${imagenames}" var="imagename">
    <img src="${pageContext.request.contextPath}/images/${imagename}">
</c:forEach>
Run Code Online (Sandbox Code Playgroud)

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

}
Run Code Online (Sandbox Code Playgroud)

而已.如果您担心HEAD和缓存标头并正确响应这些请求,请将此抽象模板用于静态资源servlet.

也可以看看:

  • +1然而,一个伟大的人的另一个伟大答案.谢谢! (3认同)

ewe*_*nli 6

我建议你解决这两个问题.有两个问题和答案都与两者有关.

  1. 如何从MySQL加载blob

    例如,请参阅检索存储为blob的图像

  2. 如何动态显示图像

    例如,请参见动态显示缩略图


归档时间:

查看次数:

79135 次

最近记录:

6 年,6 月 前