近期,在给客户做一个Demo页面时,需要用Java读取Oracle中的blob图片字段并显示,在此过程中,遇到一些问题,例如:连接oracle数据库读取blob字段数据,对图片byte数据进行缩放等;特此记录,给自己备忘,给大家参考。
整个流程分为四步,连接oracle数据库 -> 读取blob图片字段 -> 对图片进行缩放 ->把图片展示在jsp页面上。
下面进行详细描述:
1. java连接Oracle
注:数据库是Oracle10g版本为10.2.0, 在数据库中,图片字段类型为BLOB。
java中通常使用的是通过jdbc驱动来连接数据库,oracle也不例外,因此必须下载一个Oracle驱动的jdbc需要去网上进行下载,名称为 ojdbc14.jar。
下载地址为:
http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/htdocs/jdbc101040.html
下载了驱动之后,可以使用驱动里提供的接口进行连接,具体代码如下:
- import java.sql.*;
- import java.io.*;
- import javax.imageio.ImageIO;
- import java.awt.image.BufferedImage;
- import java.awt.image.AffineTransformOp;
- import java.awt.geom.AffineTransform;
- public class OracleQueryBean {
- private final String oracleDriverName = "oracle.jdbc.driver.OracleDriver";
- private Connection myConnection = null;
- /*图片表名*/
- private String strTabName;
- /*图片ID字段名*/
- private String strIDName;
- /*图片字段名*/
- private String strImgName;
- /**
- * 加载java连接Oracle的jdbc驱动
- */
- public OracleQueryBean(){
- try{
- Class.forName(oracleDriverName);
- }catch(ClassNotFoundException ex){
- System.out.println("加载jdbc驱动失败,原因:" + ex.getMessage());
- }
- }
- /**
- * 获取Oracle连接对象
- * @return Connection
- */
- public Connection getConnection(){
- try{
- //用户名+密码; 以下使用的Test就是Oracle里的表空间
- //从配置文件中读取数据库信息
- 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");
- this.strTabName = oGetPara.getPara("tablename");
- this.strIDName = oGetPara.getPara("imgidname");
- this.strImgName = oGetPara.getPara("imgname");
- String oracleUrlToConnect ="jdbc:oracle:thin:@"+strIP+":"+strPort+":"+strDBName;
- this.myConnection = DriverManager.getConnection(oracleUrlToConnect, strUser, strPassword);
- }catch(Exception ex){
- System.out.println("Can not get connection:" + ex.getMessage());
- System.out.println("请检测配置文件中的数据库信息是否正确." );
- }
- return this.myConnection;
- }
- }
2. 读取blob字段
在OracleQueryBean类中增加一个函数,来进行读取,具体代码如下:
- /**
- * 根据图片在数据库中的ID进行读取
- * @param strID 图片字段ID
- * @param w 需要缩到的宽度
- * @param h 需要缩到高度
- * @return
- */
- public byte[] GetImgByteById(String strID, int w, int h){
- //System.out.println("Get img data which id is " + nID);
- if(myConnection == null)
- this.getConnection();
- byte[] data = null;
- try {
- Statement stmt = myConnection.createStatement();
- ResultSet myResultSet = stmt.executeQuery("select " + this.strIDName + " from " + this.strTabName + " where " + this.strIDName + "=" + strID);
- StringBuffer myStringBuffer = new StringBuffer();
- if (myResultSet.next()) {
- java.sql.Blob blob = myResultSet.getBlob(this.strImgName);
- InputStream inStream = blob.getBinaryStream();
- try {
- long nLen = blob.length();
- int nSize = (int) nLen;
- //System.out.println("img data size is :" + nSize);
- data = new byte[nSize];
- inStream.read(data);
- inStream.close();
- } catch (IOException e) {
- System.out.println("获取图片数据失败,原因:" + e.getMessage());
- }
- data = ChangeImgSize(data, w, h);
- }
- System.out.println(myStringBuffer.toString());
- myConnection.commit();
- myConnection.close();
- } catch (SQLException ex) {
- System.out.println(ex.getMessage());
- }
- return data;
- }
3. 缩放图片
因为图片的大小可能不一致,但是在页面中输出的大小需要统一,所以需要
在OracleQueryBean类中增加一个函数,来进行缩放,具体代码如下:
- /**
- * 缩小或放大图片
- * @param data 图片的byte数据
- * @param w 需要缩到的宽度
- * @param h 需要缩到高度
- * @return 缩放后的图片的byte数据
- */
- private byte[] ChangeImgSize(byte[] data, int nw, int nh){
- byte[] newdata = null;
- try{
- BufferedImage bis = ImageIO.read(new ByteArrayInputStream(data));
- int w = bis.getWidth();
- int h = bis.getHeight();
- double sx = (double) nw / w;
- double sy = (double) nh / h;
- 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);
- //转换成byte字节
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ImageIO.write(bid, "jpeg", baos);
- newdata = baos.toByteArray();
- }catch(IOException e){
- e.printStackTrace();
- }
- return newdata;
- }
4. 展示在页面
页面使用OracleQueryBean来根据用户提供的图片id进行查询,在读取并进行缩放后,通过jsp页面进行展示,具体代码如下:
- <%@ page language="java" contentType="text/html;;charset=gbk" %>
- <jsp:useBean id="OrcleQuery" scope="page" class="HLFtiDemo.OracleQueryBean" />
- <%
- response.setContentType("image/jpeg");
- //图片在数据库中的 ID
- String strID = request.getParameter("id");
- //要缩略或放大图片的宽度
- String strWidth = request.getParameter("w");
- //要缩略或放大图片的高度
- String strHeight = request.getParameter("h");
- byte[] data = null;
- if(strID != null){
- int nWith = Integer.parseInt(strWidth);
- int nHeight = Integer.parseInt(strHeight);
- //获取图片的byte数据
- data = OrcleQuery.GetImgByteById(strID, nWith, nHeight);
- ServletOutputStream op = response.getOutputStream();
- op.write(data, 0, data.length);
- op.close();
- op = null;
- response.flushBuffer();
- //清除输出流,防止释放时被捕获异常
- out.clear();
- out = pageContext.pushBody();
- }
- %>
5. OracleQueryBean查询类的整体代码
OracleQueryBean.java文件代码如下所示:
- import java.sql.*;
- import java.io.*;
- import javax.imageio.ImageIO;
- import java.awt.image.BufferedImage;
- import java.awt.image.AffineTransformOp;
- import java.awt.geom.AffineTransform;
- public class OracleQueryBean {
- private final String oracleDriverName = "oracle.jdbc.driver.OracleDriver";
- private Connection myConnection = null;
- /*图片表名*/
- private String strTabName;
- /*图片ID字段名*/
- private String strIDName;
- /*图片字段名*/
- private String strImgName;
- /**
- * 加载java连接Oracle的jdbc驱动
- */
- public OracleQueryBean(){
- try{
- Class.forName(oracleDriverName);
- }catch(ClassNotFoundException ex){
- System.out.println("加载jdbc驱动失败,原因:" + ex.getMessage());
- }
- }
- /**
- * 获取Oracle连接对象
- * @return Connection
- */
- public Connection getConnection(){
- try{
- //用户名+密码; 以下使用的Test就是Oracle里的表空间
- //从配置文件中读取数据库信息
- 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");
- this.strTabName = oGetPara.getPara("tablename");
- this.strIDName = oGetPara.getPara("imgidname");
- this.strImgName = oGetPara.getPara("imgname");
- String oracleUrlToConnect ="jdbc:oracle:thin:@"+strIP+":"+strPort+":"+strDBName;
- this.myConnection = DriverManager.getConnection(oracleUrlToConnect, strUser, strPassword);
- }catch(Exception ex){
- System.out.println("Can not get connection:" + ex.getMessage());
- System.out.println("请检测配置文件中的数据库信息是否正确." );
- }
- return this.myConnection;
- }
- /**
- * 根据图片在数据库中的ID进行读取
- * @param strID 图片字段ID
- * @param w 需要缩到的宽度
- * @param h 需要缩到高度
- * @return 缩放后的图片的byte数据
- */
- public byte[] GetImgByteById(String strID, int w, int h){
- //System.out.println("Get img data which id is " + nID);
- if(myConnection == null)
- this.getConnection();
- byte[] data = null;
- try {
- Statement stmt = myConnection.createStatement();
- ResultSet myResultSet = stmt.executeQuery("select " + this.strIDName + " from " + this.strTabName + " where " + this.strIDName + "=" + strID);
- StringBuffer myStringBuffer = new StringBuffer();
- if (myResultSet.next()) {
- java.sql.Blob blob = myResultSet.getBlob(this.strImgName);
- InputStream inStream = blob.getBinaryStream();
- try {
- long nLen = blob.length();
- int nSize = (int) nLen;
- //System.out.println("img data size is :" + nSize);
- data = new byte[nSize];
- inStream.read(data);
- inStream.close();
- } catch (IOException e) {
- System.out.println("获取图片数据失败,原因:" + e.getMessage());
- }
- data = ChangeImgSize(data, w, h);
- }
- System.out.println(myStringBuffer.toString());
- myConnection.commit();
- myConnection.close();
- } catch (SQLException ex) {
- System.out.println(ex.getMessage());
- }
- return data;
- }
- /**
- * 根据图片在数据库中的ID进行读取,显示原始大小的图片
- * @param strID 图片字段ID
- * @return 读取后的图片byte数据
- */
- public byte[] GetImgByteById(String strID){
- //System.out.println("Get img data which id is " + nID);
- if(myConnection == null)
- this.getConnection();
- byte[] data = null;
- try {
- Statement stmt = myConnection.createStatement();
- ResultSet myResultSet = stmt.executeQuery("select " + this.strIDName + " from " + this.strTabName + " where " + this.strIDName + "=" + strID);
- StringBuffer myStringBuffer = new StringBuffer();
- if (myResultSet.next()) {
- java.sql.Blob blob = myResultSet.getBlob(this.strImgName);
- InputStream inStream = blob.getBinaryStream();
- try {
- long nLen = blob.length();
- int nSize = (int) nLen;
- data = new byte[nSize];
- inStream.read(data);
- inStream.close();
- } catch (IOException e) {
- System.out.println("获取图片数据失败,原因:" + e.getMessage());
- }
- }
- System.out.println(myStringBuffer.toString());
- myConnection.commit();
- myConnection.close();
- } catch (SQLException ex) {
- System.out.println(ex.getMessage());
- }
- return data;
- }
- /**
- * 缩小或放大图片
- * @param data 图片的byte数据
- * @param w 需要缩到的宽度
- * @param h 需要缩到高度
- * @return
- */
- private byte[] ChangeImgSize(byte[] data, int nw, int nh){
- byte[] newdata = null;
- try{
- BufferedImage bis = ImageIO.read(new ByteArrayInputStream(data));
- int w = bis.getWidth();
- int h = bis.getHeight();
- double sx = (double) nw / w;
- double sy = (double) nh / h;
- 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);
- //转换成byte字节
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ImageIO.write(bid, "jpeg", baos);
- newdata = baos.toByteArray();
- }catch(IOException e){
- e.printStackTrace();
- }
- return newdata;
- }
- }