簡體   English   中英

如何在 JSP 頁面中從數據庫中檢索和顯示圖像?

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

如何在 JSP 頁面中從數據庫中檢索和顯示圖像?

讓我們分步驟看看會發生什么:

  • 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 中,您可以使用通常的Java IO方式將此byte[]InputStream寫入響應的OutputStream
  • 需要指示客戶端將數據作為圖像處理,因此至少還需要設置Content-Type響應頭。 您可以根據圖像文件擴展名通過ServletContext#getMimeType()獲得正確的圖像文件擴展名,您可以通過web.xml <mime-mapping>擴展和/或覆蓋。

應該是這樣。 它幾乎自己編寫代碼。 讓我們從 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">

如有必要,您還可以在使用JSTL進行迭代時使用EL動態設置src

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

然后定義/創建一個servlet ,它偵聽/images/* URL 模式上的 GET 請求,下面的示例使用普通的 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

也可以看看:

我建議您將其視為兩個問題。 有幾個問題和答案與兩者相關。

  1. 如何從 MySQL 加載 blob

    參見例如檢索存儲為 blob 的圖像

  2. 如何動態顯示圖像

    參見例如動態顯示縮略圖

如果未顯示,請嘗試刷新並關閉輸出流。 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();

我已經使用 Oracle 數據庫在 JSP 中編寫和配置了代碼。 希望它會有所幫助。

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
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.http.HttpSession;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class displayfetchimage
 */
@WebServlet("/displayfetchimage")
public class displayfetchimage extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public displayfetchimage() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        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 = employee.DbConnection.getDatabaseConnection();
        HttpSession session = (HttpSession) request.getSession();
        String ID = session.getAttribute("userId").toString().toLowerCase();
        try {
            stmt = conn.createStatement();
            sql = "select user_image from employee_data WHERE username='" + ID + "' and rownum<=1";
            ResultSet result = stmt.executeQuery(sql);
            if (result.next()) {
                in = result.getBinaryStream(1);// Since my data was in first 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(displayfetchimage.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());
            }
        }

    }

    // response.getWriter().append("Served at: ").append(request.getContextPath());
    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
     *      response)
     */

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, 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 = employee.DbConnection.getDatabaseConnection();
        HttpSession session = (HttpSession) request.getSession();
        String ID = session.getAttribute("userId").toString().toLowerCase();
        try {
            stmt = conn.createStatement();
            sql = "select user_image from employee_data WHERE username='" + ID + "' and rownum<=1";
            ResultSet result = stmt.executeQuery(sql);
            if (result.next()) {
                in = result.getBinaryStream(1);
            }
            bin = new BufferedInputStream(in);
            bout = new BufferedOutputStream(out);
            int ch = 0;
            while ((ch = bin.read()) != -1) {
                bout.write(ch);
            }

        } catch (SQLException ex) {
            Logger.getLogger(displayfetchimage.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());
            }
        }

    }

}

您還可以創建用於顯示圖像的自定義標簽。

1)創建自定義標簽java類和tld文件。

2) 編寫邏輯來顯示圖像,例如通過 Base64 將 byte[] 轉換為字符串。

因此,無論您是在單個 jsp 頁面中僅顯示一張圖像還是多張圖像,它都會用於每個圖像。

我使用了 SQL SERVER 數據庫,所以答案的代碼是一致的。 你所要做的就是在你的 jsp 頁面中包含一個<img>標簽,並像這樣從它的 src 屬性調用一個 servlet

<img width="200" height="180" src="DisplayImage?ID=1">

這里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());
        }
    }


    }  
}  

在執行您的 jsp 或 html 文件后,您將在屏幕上看到圖像。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM