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


 


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

1 // pass:錯誤信息為便於查看進行了回車,真實情況是全在一行
2 Type definition error: 
3 [simple type, class oracle.jdbc.OracleConnection]; 
4 nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
5 Direct self-reference leading to cycle (through reference chain:
6 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() 方法,結果發現又出現問題了,報了個如下的問題:

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

嗯,很無奈、很奇怪,但是沒法啊,只能繼續在網上找資料,最終找到了問題所在,問題解釋如下:

我們接收到的這個數據實例是個包裹着 java.sql.Blob 外殼的 Proxy 類型的實例。因此,當我們想操作這個 Blob 數據時就需要針對這個被包裝的 Blob 進行去殼,核心代碼如下:

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

資料出處:隔壁老王

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


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

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

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

 1 package ***.***.***.***.***.util; 
 2 
 3 import java.io.ByteArrayOutputStream;
 4 import java.io.IOException;
 5 import java.io.InputStream;
 6 import java.lang.reflect.Proxy;
 7 import java.sql.Blob;
 8 import java.sql.SQLException;
 9 
10 import org.hibernate.engine.jdbc.SerializableBlobProxy;
11 
12 import com.primeton.xfire.util.Base64;
13 
14 /**
15  * @descript BLOB/BASE64相互轉化工具類
16  * @author ***
17  *
18  */
19 public class BlobAndBase64Util {
20 
21     Blob blob;
22 
23     // BLOB 轉 BASE64
24     /*
25      * @Description :將BLOB類型數據轉化成BASE64類型
26      * @param : blobDate ———— blob類型的數據,直接扔進去就好
27      */
28     public static String getBase64InBlob(Object blobDate) {
29         String result = new String();
30         try {
31             // 獲取代理實例的調用處理程序
32             SerializableBlobProxy proxy = (SerializableBlobProxy) Proxy.getInvocationHandler(blobDate);
33             // 獲取被代理對象的BLOB數據對象
34             Blob realBlob = proxy.getWrappedBlob();
35             // 創建byte數組輸出對象
36             ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
37             // 創建一個長度為100的byte數組
38             byte[] buff = new byte[100];
39             int rc = 0;
40             // 獲取BLOB數據對象的二進制流
41             InputStream binaryStream = realBlob.getBinaryStream();
42             while ((rc = binaryStream.read(buff, 0, 100)) > 0) {
43                 byteArrayOutputStream.write(buff, 0, rc);
44             }
45             byte[] byteArray = byteArrayOutputStream.toByteArray();
46             result = Base64.encode(byteArray);
47         } catch (IOException e) {
48             e.printStackTrace();
49         } catch (SQLException e) {
50             e.printStackTrace();
51         }
52         return result;
53     }
54 
55     // BLOB 轉 BASE64
56     // public static String getBlobInBase64(Object blobDate) {
57     //
58     // return null;
59     // }
60 }

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


總結:

  • 遇到問題多查看報錯日志信息,只有報錯信息看明白了才能對症下葯,否則事倍功半;
  • 多細心嘗試;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM