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