java—如何在jsp页面中检索和显示数据库中的图像?

qlvxas9a  于 2021-07-11  发布在  Java
关注(0)|答案(5)|浏览(405)

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

yyhrrdl8

yyhrrdl81#

让我们分步看看应该发生什么:
jsp基本上是一种生成html输出的视图技术。
要用html显示图像,需要html <img> 元素。
要让它定位一个图像,您需要指定它的位置 src 属性。
这个 src 属性需要指向有效的 http:// 因此不是本地磁盘文件系统路径 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 在数据库中,jdbcapi提供 ResultSet#getBytes() 以及 ResultSet#getBinaryStream() 为此,jpaapi提供了 @Lob 为了这个。
在servlet中,您可以编写 byte[] 或者 InputStreamOutputStream 通常的javaio方式的响应。
需要指示客户端将数据作为图像处理,因此至少 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">

如果需要,还可以动态设置 src 在使用jstl迭代时使用el:

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

然后定义/创建一个servlet,该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);
        }
    }

}

就这样。如果您担心head和缓存头以及对这些请求的正确响应,请将此抽象模板用于静态资源servlet。

另请参见:

在基于servlet的应用程序中,我应该如何连接到jdbc数据库/数据源?
如何上传图片并保存到数据库中?
在javaweb应用程序中从应用服务器外部提供静态数据的最简单方法

ozxc1zmp

ozxc1zmp2#

我建议你把这当作两个问题来处理。有几个问题和答案都与这两者有关。
如何从mysql加载blob
例如,请参见检索存储为blob的图像
如何动态显示图像
例如,请参见动态显示缩略图

eqoofvh9

eqoofvh93#

如果输出流不显示,请尝试刷新并关闭它。
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();

wgxvkvu9

wgxvkvu94#

您还可以创建用于显示图像的自定义标记。
1) 创建自定义标记java类和tld文件。
2) 写入逻辑以显示按base64将字节[]转换为字符串的图像。
因此,无论您是在单个jsp页面中仅显示一个图像还是显示多个图像,它都用于每个图像。

sigwle7e

sigwle7e5#

我用的是sqlserver数据库,所以答案的代码是一致的。你所要做的就是包括一个 <img> 在jsp页面中添加标签,并从其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文件之后,您将看到屏幕上的图像。

相关问题