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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 06:20:03  来源:igfitidea点击:

How to retrieve and display images from a database in a JSP page?

javaimagejspservlets

提问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.

我建议您将其视为两个问题。有几个问题和答案与两者相关。

  1. How to load blob from MySQL

    See for instance Retrieve image stored as blob

  2. How to display image dynamically

    See for instance Show thumbnail dynamically

  1. 如何从 MySQL 加载 blob

    参见例如检索存储为 blob 的图像

  2. 如何动态显示图像

    参见例如动态显示缩略图

回答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 srcattribute.
  • The srcattribute 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 InputStreamfrom the DB, the JDBC APIoffers the ResultSet#getBytes()and ResultSet#getBinaryStream()for this, and JPA APIoffers @Lobfor this.
  • In the Servlet you can just write this byte[]or InputStreamto the OutputStreamof 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-Typeresponse 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.
  • 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>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 srcwith ELwhile iterating using JSTL:

必要时,可以动态地也设置srcEL而使用迭代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();