BLOB轉BASE64—— 詳細工具類(可直接使用)

BLOB轉BASE64方法—— 詳細工具類


在近期的項目開發中,第一次遇到了BLOB類型數據的讀取,但是的業務是這樣的,需要將數據庫中的某些信息(包含有BLOB類型的數據)讀取出來傳給前臺,本來很簡單的一個業務,當時只以爲是可以按照正常類型的數據進行處理,結果就掉進坑裏了,首先遇到的是:

// pass:錯誤信息爲便於查看進行了回車,真實情況是全在一行
Type definition error: 
[simple type, class oracle.jdbc.OracleConnection]; 
nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
Direct self-reference leading to cycle (through reference chain:
java.util.ArrayList[1]->java.util.LinkedHashMap["data"]->java.util.ArrayList[0]->java.util.HashMap["ABC"]->com.sun.proxy.$Proxy117["wrappedBlob"]->oracle.sql.BLOB["dbaccess"]->oracle.jdbc.driver.T4CConnection["wrapper"])

意思很簡單,就是說我這個(java.util.HashMap["ABC"]ABC 這個數據類型定義錯誤,(com.sun.proxy.$Proxy117["wrappedBlob"]) 從這裏可以看出來 ABC 它是代理類型的BLOB數據(這麼說不知道嚴禁不嚴謹),那既然這樣,我們需要把 ABC 這個數據進行格式轉化後再進行保存到數據集合中,說幹就幹,考慮後選擇把BLOB數據轉換成BASE64類型的(base64百度百科),在轉換時直接使用了Base64.encode() 方法,結果發現又出現問題了,報了個如下的問題:

oracle.sql.BLOB cannot be cast to oracle.sql.BLOB

嗯,很無奈、很奇怪,但是沒法啊,只能繼續在網上找資料,最終找到了問題所在,問題解釋如下:
我們接收到的這個數據實例是個包裹着java.sql.Blob外殼的Proxy類型的實例。因此,當我們想操作這個Blob數據時就需要針對這個被包裝的Blob進行去殼,核心代碼如下:

	SerializableBlobProxy proxy = (SerializableBlobProxy )Proxy.getInvocationHandler(blob); 
  java.sql.Blob realBlob = proxy.getWrappedBlob();

資料出處:隔壁老王
現在弄明白了問題的原因,也找到了相應的解決辦法,那就開始繼續往下處理吧。


經過開始的摸索,排除了各種問題,那接下來就開始整理思路編寫代碼了;
思路如下:

  1. 去殼,將BLOB數據的真正數據取出來;
  2. 轉流,將去殼後的數據轉換成 ’ byte[] ’ 的形式(爲下一步做準備);
  3. 使用BASE64的數據轉換方法進行數據轉換;

現在思路通了,開始敲代碼:
BlobAndBase64Util.java

package ***.***.***.***.***.util; // 路徑信息不便展示

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Proxy;
import java.sql.Blob;
import java.sql.SQLException;

import org.hibernate.engine.jdbc.SerializableBlobProxy;

import com.primeton.xfire.util.Base64;

/**
 * @descript BLOB/BASE64相互轉化工具類
 * @author ***
 *
 */
public class BlobAndBase64Util {

	Blob blob;

	// BLOB 轉 BASE64
	/*
	 * @Description :將BLOB類型數據轉化成BASE64類型
	 * @param : blobDate ———— blob類型的數據,直接扔進去就好
	 */
	public static String getBase64InBlob(Object blobDate) {
		String result = new String();
		try {
			// 獲取代理實例的調用處理程序
			SerializableBlobProxy proxy = (SerializableBlobProxy) Proxy.getInvocationHandler(blobDate);
			// 獲取被代理對象的BLOB數據對象
			Blob realBlob = proxy.getWrappedBlob();
			// 創建byte數組輸出對象
			ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
			// 創建一個長度爲100的byte數組
			byte[] buff = new byte[100];
			int rc = 0;
			// 獲取BLOB數據對象的二進制流
			InputStream binaryStream = realBlob.getBinaryStream();
			while ((rc = binaryStream.read(buff, 0, 100)) > 0) {
				byteArrayOutputStream.write(buff, 0, rc);
			}
			byte[] byteArray = byteArrayOutputStream.toByteArray();
			result = Base64.encode(byteArray);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}

	// BLOB 轉 BASE64
	// public static String getBlobInBase64(Object blobDate) {
	//
	// return null;
	// }
}

經測試後以正確轉化成String類型的數據;


總結:

  • 遇到問題多查看報錯日誌信息,只有報錯信息看明白了才能對症下藥,否則事倍功半;
  • 多細心嘗試;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章