如何处理BLOB类型数据之三:使用Servlet在页面上显示BLOB中的图片

187 篇文章 2 订阅
实验环境:JDeveloper 11.1.2.0.0。
接上一个实验《 如何处理BLOB类型数据之二:下载BLOB内容并保存到文件中 》。

我的设计思想:
这其实是一个动态显示图片的问题,类似于很多网站上登录时要求输入的图片认证码。
一开始,根据前面的思路,我打算继续使用ADF BC的来显示BLOB中的图片内容,后来发现这个功能相对来说比较独立,于是就想写一个通用的,这样没有ADF也可以使用。
于是,我参考了《 一个读取BLOB中图片的Servlet代码 》,写了一个Servlet。

1. 新建页面:get_image_from_blob.jspx
<af:image source="/blobimageservlet?id=75" id="i5"/>
我这里只是测试Servlet是否工作正常,因此参数id给的是常量75,因为我上传的id=75的文件是一个.jpg。
你可以根据你的需要,把参数动态设置。

2. 创建Servlet:BlobImageServlet.java
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.OutputStream;

import java.io.PrintWriter;

import java.sql.Blob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import java.sql.SQLException;

import javax.naming.Context;
import javax.naming.InitialContext;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import javax.sql.DataSource;

public class BlobImageServlet extends HttpServlet {
private static final String CONTENT_TYPE = "image/jpg; charset=utf-8";

public void init(ServletConfig config) throws ServletException {
super.init(config);
}

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType(CONTENT_TYPE);
String idStr = request.getParameter("id");
int id = -1;
if (idStr != null) {
id = Integer.parseInt(idStr);
}

OutputStream os = response.getOutputStream();
Connection conn = null;

try {
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/uploadFileToBlobConnDS");
conn = ds.getConnection();
PreparedStatement statement =
conn.prepareStatement("SELECT UploadedFiles.ID," + 
" UploadedFiles.FILENAME, " +
" UploadedFiles.CONTENT " + 
"FROM UPLOADED_FILES UploadedFiles " +
"WHERE UploadedFiles.ID = ?");

statement.setInt(1, new Integer(id));
ResultSet rs = statement.executeQuery();
if (rs.next()) {
Blob blob = rs.getBlob("Content");
BufferedInputStream in = new BufferedInputStream(blob.getBinaryStream());
int b;
byte[] buffer = new byte[10240];
while ((b = in.read(buffer, 0, 10240)) != -1) {
os.write(buffer, 0, b);
}
os.close();
}
} catch (Exception e) {
e.printStackTrace(); 
} finally {
try {
if (conn != null) {
conn.close();
}
} catch (SQLException sqle) {
System.out.println("SQLException error");
}
}
}
}

3. 运行,访问get_image_from_blob.jspx,显示BLOB中的图片内容
唉,斯人已逝,永远怀念的邓丽君......


4. 深入分析
使用Servlet来显示BLOB中的图片内容,可能会引起性能问题。因为每一个BLOB图片显示,都要占用一个数据库连接。
可以考虑修改Serverlt的逻辑如下:
如果在某个路径下没有某个图片,那么,再去访问数据库,获取图片,并生成在该路径下。
否则,直接访问已经生成的图片文件。
其中,为了保证图片名称的唯一性,图片名称包含时间戳。

5. 问题:如果使用ADF BC该如何做?
我认为在某些情况下,使用ADF BC还是比较方便的,比如一个天气预报表格中,某一列用小图片来表示不同的天气情况。
因为省去了连接数据库的代码,不会有性能问题。
而且可以非常方便的获取BlobDomain对象:row.Content。如果支持如下写法就更好了:
<af:image source="#{row.Content}" id="i5"/>
可惜这样写,是无法显示出图片的。
可以在Managed Bean中写一个方法来处理BlobDomain,放到image的source属性中。
这个以后有空在写吧。

Project 下载: UploadFileToBlob_DownloadBlobToFile_getBlobImage.7z

参考文献:

1. http://kr.forums.oracle.com/forums/thread.jspa?threadID=614954。

http://maping930883.blogspot.com/2011/08/adf097blobblob.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Java ,可以使用 JDBC API 将从 MySQL 数据检索到的 BLOB 数据转换为图片。然后,可以使用 Servlet 或 JSP 将图片嵌入到 HTML ,以在 Web 页面显示图片。下面是具体的步骤: 1. 使用 JDBC API 连接到 MySQL 数据库,并执行 SELECT 语句以检索包含图片BLOB 列。 ```java Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase", "username", "password"); PreparedStatement stmt = conn.prepareStatement("SELECT data FROM images WHERE id = ?"); stmt.setInt(1, 1); ResultSet rs = stmt.executeQuery(); ``` 其,1 是图片所在行的 ID。 2. 从 ResultSet 对象提取 BLOB的二进制数据。 ```java if (rs.next()) { Blob blob = rs.getBlob("data"); InputStream inputStream = blob.getBinaryStream(); } ``` 3. 将二进制数据转换为图片,并将其写入 Servlet 或 JSP 的输出流。 ```java response.setContentType("image/jpeg"); // 设置响应内容类型图片类型 OutputStream outputStream = response.getOutputStream(); byte[] buffer = new byte[4096]; // 缓冲区大小 int bytesRead = -1; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); // 将图片数据写入输出流 } inputStream.close(); outputStream.close(); ``` 其,response.setContentType() 方法用于设置响应内容类型图片类型,getOutputStream() 方法用于获取输出流,write() 方法用于将图片数据写入输出流。 4. 在 HTML 嵌入图片。 ```html <img src="/imageServlet?id=1" alt="example"> ``` 其,src 属性指向 Servlet 或 JSP 的 URL,id 参数指定图片所在行的 ID。 完整的代码示例如下: ImageServlet.java: ```java import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.sql.Blob; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ImageServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase", "username", "password"); PreparedStatement stmt = conn.prepareStatement("SELECT data FROM images WHERE id = ?"); stmt.setInt(1, Integer.parseInt(request.getParameter("id"))); ResultSet rs = stmt.executeQuery(); if (rs.next()) { Blob blob = rs.getBlob("data"); InputStream inputStream = blob.getBinaryStream(); response.setContentType("image/jpeg"); OutputStream outputStream = response.getOutputStream(); byte[] buffer = new byte[4096]; int bytesRead = -1; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } inputStream.close(); outputStream.close(); } } catch (Exception e) { e.printStackTrace(); } } } ``` index.jsp: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Image Example</title> </head> <body> <img src="/imageServlet?id=1" alt="example"> </body> </html> ``` 其,/imageServlet?id=1 是 Servlet 的 URL,id 参数指定图片所在行的 ID。将 ImageServlet.java 和 index.jsp 部署到 Web 服务器,访问 index.jsp 即可在 Web 页面显示图片

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值