您的位置:首页 > 其它

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

2014-08-20 19:49 711 查看
实验环境: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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐