Java从数据库中读取Blob图片并显示的方法
在Java Web开发中,将图片以BLOB(Binary Large Object)形式存储在数据库中是常见需求。本文将演示如何通过JDBC驱动连接Oracle和MySQL数据库,读取二进制流数据,并在Servlet中将其转换为JPEG格式输出至JSP页面,支持图片缩放功能。
第一种方案:直接流式输出
该方法的核心是将数据库中的Blob字段转换为输入流,通过Response的OutputStream直接写入客户端浏览器。此方式适用于不需要在前端对图片进行处理或缩放的场景。
第1步:建立数据库连接并获取输入流
首先,使用JDBC获取连接,执行查询语句提取Blob列的二进制流。关键操作包括:
- 调用 PreparedStatement.executeQuery() 获取结果集。
- 使用 rs.getBinaryStream(1) 获取Blob对应的InputStream。
Connection conn = DBManager.getConnection();
String sql = "SELECT picture FROM teacher WHERE id=1";
PreparedStatement ps = null;
ResultSet rs = null;
InputStream is = null;
OutputStream os = null;
try {
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
if(rs.next()){
is = rs.getBinaryStream(1); // 获取图片二进制流
}
// ... 后续输出逻辑
}
第2步:配置响应头并写入输出流
设置Servlet或页面的Content-Type为 text/html 或具体的图片类型,获取 response.getOutputStream(),循环读取输入流数据并写入输出流。务必在 finally 块中关闭所有资源以防内存泄漏。
response.setContentType("text/html"); // 实际应用中建议设为 image/jpeg
os = response.getOutputStream();
byte buf[] = new byte[1024];
int num;
while((num=is.read(buf))!=-1){
os.write(buf, 0, num);
}
// 关闭资源的代码略
第3步:在JSP页面上引用
在HTML中使用 <img> 标签,src属性指向处理图片的Servlet地址。
第二种方案:带缩放的完整流程(针对Oracle)
当需要统一图片尺寸时,需先将BLOB转为字节数组,利用Java AWT进行缩放,再转回字节输出。以下示例基于Oracle数据库。
第1步:配置数据库连接参数
创建一个工具类 OracleQueryBean,负责加载Oracle JDBC驱动并建立连接。连接信息建议从配置文件读取以提高灵活性。
public Connection getConnection(){
GetPara oGetPara = new GetPara();
String strIP = oGetPara.getPara("serverip");
String strPort = oGetPara.getPara("port");
String strDBName = oGetPara.getPara("dbname");
String strUser = oGetPara.getPara("user");
String strPassword = oGetPara.getPara("password");
String oracleUrlToConnect = "jdbc:oracle:thin:@"+strIP+":"+strPort+":"+strDBName;
this.myConnection = DriverManager.getConnection(oracleUrlToConnect, strUser, strPassword);
return this.myConnection;
}
第2步:读取Blob字段并转换为字节数组
在 GetImgByteById 方法中,执行SQL查询获取Blob对象,调用 blob.getBinaryStream() 读取数据。注意处理大文件时的长度转换。
java.sql.Blob blob = myResultSet.getBlob(this.strImgName);
InputStream inStream = blob.getBinaryStream();
long nLen = blob.length();
int nSize = (int) nLen;
data = new byte[nSize];
inStream.read(data); // 注意实际使用中可能需要循环读取以保证完整性
inStream.close();
第3步:实现图片缩放功能
使用 javax.imageio.ImageIO 和 java.awt.geom.AffineTransform 对图像进行等比或非等比缩放。创建指定宽高的BufferedImage,将原始图像绘制其中,最后写回字节数组。
private byte[] ChangeImgSize(byte[] data, int nw, int nh){
BufferedImage bis = ImageIO.read(new ByteArrayInputStream(data));
double sx = (double) nw / bis.getWidth();
double sy = (double) nh / bis.getHeight();
AffineTransform transform = new AffineTransform();
transform.setToScale(sx, sy);
AffineTransformOp ato = new AffineTransformOp(transform, null);
BufferedImage bid = new BufferedImage(nw, nh, BufferedImage.TYPE_3BYTE_BGR);
ato.filter(bis, bid);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bid, "jpeg", baos); // 也可根据原图格式选择 png 等
return baos.toByteArray();
}
第4步:在JSP中展示并处理请求
JSP页面接收ID及宽高参数,实例化Bean获取处理后的字节数组,设置响应类型为 image/jpeg 并写出。最后需清除JSP隐含的输出缓冲区。
第三种方案:MySQL环境下的Servlet实现
对于MySQL数据库,操作流程类似,主要区别在于Driver类和URL格式。此处提供一个完整的Servlet类 ReadPhoto 示例。
第1步:Servlet核心逻辑
在 doGet 中,获取图片ID,查询数据库获得Blob流。为了确保兼容性,可以将读取到的 BufferedImage 重新编码为JPEG格式输出。
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
String idParam = request.getParameter("id");
if(idParam == null) return;
response.setContentType("image/jpeg");
try {
InputStream is = query_getPhotoImageBlob(Integer.parseInt(idParam));
if(is != null){
is = new BufferedInputStream(is);
BufferedImage bi = ImageIO.read(is);
OutputStream os = response.getOutputStream();
// 使用JPEG编码器重新输出,确保格式统一
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);
encoder.encode(bi);
os.flush();
os.close();
}
} catch(Exception e) { e.printStackTrace(); }
}
第2步:数据库查询辅助方法
封装一个静态方法用于执行MySQL查询,返回图片的InputStream。注意处理资源释放。
public static InputStream query_getPhotoImageBlob(int id) throws SQLException {
String sql = "select photo from photo where id=?";
Connection con = DriverManager.getConnection(...);
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setInt(1, id);
ResultSet rs = pstmt.executeQuery();
InputStream result = null;
if(rs.next()){ result = rs.getBlob("photo").getBinaryStream(); }
// 关闭资源...
return result;
}
第3步:注册Servlet映射
在 web.xml 中配置该Servlet,定义URL Pattern以便前端访问。
第4步:前端JSP调用
通过 <img> 标签指向配置的Servlet路径,并传入图片ID作为参数。
以上就是Java从数据库中读取Blob对象图片并显示的详细内容,更多关于Java数据库交互的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













