博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
oracle blob 反序列化错误
阅读量:5221 次
发布时间:2019-06-14

本文共 8562 字,大约阅读时间需要 28 分钟。

代码的目的是先将一个配置类JobConfig序列化存进Oracle中的Blob中,然后查的时候反序列化出来。

先看一下控制台报错 

### Cause: com.audaque.lib.core.exception.AdqRuntimeException: error on getResult; nested exception is java.io.StreamCorruptedException: invalid stream header: 00540001    at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:23)    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:107)    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:98)    at sun.reflect.GeneratedMethodAccessor133.invoke(Unknown Source)    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)    at java.lang.reflect.Method.invoke(Method.java:498)    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:354)    ... 84 moreCaused by: com.audaque.lib.core.exception.AdqRuntimeException: error on getResult; nested exception is java.io.StreamCorruptedException: invalid stream header: 00540001    at com.audaque.datadiscovery.mybatis.SerializeHandler.getResult(SerializeHandler.java:50)    at org.apache.ibatis.executor.resultset.FastResultSetHandler.getPropertyMappingValue(FastResultSetHandler.java:325)    at org.apache.ibatis.executor.resultset.FastResultSetHandler.applyPropertyMappings(FastResultSetHandler.java:301)    at org.apache.ibatis.executor.resultset.NestedResultSetHandler.getRowValue(NestedResultSetHandler.java:135)    at org.apache.ibatis.executor.resultset.NestedResultSetHandler.handleRowValues(NestedResultSetHandler.java:102)    at org.apache.ibatis.executor.resultset.FastResultSetHandler.handleResultSet(FastResultSetHandler.java:188)    at org.apache.ibatis.executor.resultset.NestedResultSetHandler.handleResultSet(NestedResultSetHandler.java:73)

Mybatis  resultMap

报错原因是查询后设置结果时,Job对象的JobConfig属性反序列化失败。

 使用的是MyBatis框架,针对这个JobConfig 配置类,做了一个TypeHanlder,下面是这个TypeHandlder

public class SerializeHandler implements TypeHandler {
@Override public void setParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
if (parameter == null) {
ps.setString(i, null); return; } try {
byte[] ss = SerializeUtils.serializeObject(parameter); ps.setBytes(i, ss); } catch (IOException e) {
throw new AdqRuntimeException("error on setParameter" ,e); } } @Override public Object getResult(ResultSet rs, String columnName) throws SQLException {
Object object = null; try {
      //反序列化报错 object = SerializeUtils.deserializeObject(rs.getBytes(columnName)); } catch (IOException e) {
throw new AdqRuntimeException("error on getResult" ,e); } catch (ClassNotFoundException e) {
throw new AdqRuntimeException("error on getResult" ,e); } return object; } @Override public Object getResult(CallableStatement cs, int columnIndex) throws SQLException {
Object object = null; try {
object = SerializeUtils.deserializeObject(cs.getBytes(columnIndex)); } catch (IOException e) {
throw new AdqRuntimeException("error on getResult" ,e); } catch (ClassNotFoundException e) {
throw new AdqRuntimeException("error on getResult" ,e); } return object; } @Override public Object getResult(ResultSet rs, int columnIndex) throws SQLException {
Object object = null; try {
object = SerializeUtils.deserializeObject(rs.getBytes(columnIndex)); } catch (IOException e) {
throw new AdqRuntimeException("error on getResult" ,e); } catch (ClassNotFoundException e) {
throw new AdqRuntimeException("error on getResult" ,e); } return object; } }

TypeHandler中有一个序列化工具类

public final class SerializeUtils {    /**     *      * @param object is want to serialize     * @return     * @throws IOException     */    public static 
byte[] serializeObject(T object) throws IOException { byte[] buffer = null; ByteArrayOutputStream bos = null; ObjectOutputStream oos = null; long start = System.currentTimeMillis(); try{ bos = new ByteArrayOutputStream(); oos = new ObjectOutputStream(bos); oos.writeObject(object); oos.flush(); buffer = bos.toByteArray(); }catch(IOException ex){ throw ex; }finally{ if(oos != null){ oos.close(); } if(bos != null){ bos.close(); } long end = System.currentTimeMillis();// System.out.println("serializeObject "+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(start))+" costs "+(end-start) + " ms"); } return buffer; } /** * * @param buf is want to deserialize * @return * @throws IOException * @throws ClassNotFoundException */ @SuppressWarnings({ "unchecked" }) public static
T deserializeObject(byte[] buf) throws IOException, ClassNotFoundException { T object = null; ByteArrayInputStream bis = null; ObjectInputStream ois = null; long start = System.currentTimeMillis(); try{ bis = new ByteArrayInputStream(buf); ois = new ObjectInputStream(bis); object = (T) ois.readObject(); }catch(IOException ex){ throw ex; }finally{ if(ois != null){ ois.close(); } if(bis != null){ bis.close(); } long end = System.currentTimeMillis();// System.out.println("deserializeObject "+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(start))+" costs "+(end-start) + " ms"); } return object; }

我先测试了工具类SerializeUtils是否有问题,测试了一下是没有问题的。

我在序列化之后调用反序列化方法,也是没有问题的。

问题出在从数据库查询出来后,查了一下读取BLOB对象为byte的java代码,java.sql.Blob对象转化byte数组  和 oracle.sql.Blob对象转化byte数组的方法不同,如果使用 oracle.sql.Blob.getBytes方法转化,则会报java.io.StreamCorruptedException: invalid stream header: 006C0001 错误

    QueryRunner run = new QueryRunner(true);        String  querySql  = "SELECT JOB_CONFIG FROM adqm_job where job_id = 141";        Object[] array = run.query(con, querySql, new ArrayHandler());        Blob blob= (Blob) array[0];        byte[] returnValue =  blob.getBytes(1, (int) blob.length());        System.out.println(Arrays.toString(returnValue));        InputStream is = null;        BLOB blob1 = (BLOB)(array[0]);        byte[] b = null;        try {            is = blob1.getBinaryStream();            b = new byte[(int) blob1.length()];            is.read(b);        } catch (Exception e) {            e.printStackTrace();        }

但是系统代码使用的是 rs.getBytes(columnName)代码,那是否是getBytes代码有问题吗?

Connection con = DBUtil.getConnection();        String  querySql  = "SELECT JOB_CONFIG FROM adqm_job where job_id = 141";        PreparedStatement preparedStatement =  con.prepareStatement(querySql);        ResultSet resultSet =  preparedStatement.executeQuery();        while (resultSet.next())        {            byte []bytes= resultSet.getBytes("JOB_CONFIG");            SerializeUtils.deserializeObject(bytes);        }        DBUtil.close(con);

测试了一下使用  rs.getBytes(columnName) 取出byte数组是 反序列化是没有问题的。

 

BUG的原因还是没有找到,我猜想的原因是object = SerializeUtils.deserializeObject(rs.getBytes(columnName)); 中rs.getBytes(columnName)的底层实现为((BLOB)(rs.getBlob)).getBytes(); 

最后我将TypeHandler 的getResult方法中改为

@Override    public Object getResult(ResultSet rs, String columnName) throws SQLException {        Object object = null;        // 集成工作流BUG修复       try {            Blob blob = rs.getBlob(columnName);            byte[] returnValue = null;            if (null != blob) {                returnValue = blob.getBytes(1, (int) blob.length());                object =  SerializeUtils.deserializeObject(returnValue);            }        //     代码        //    object =  SerializeUtils.deserializeObject(rs.getBytes(columnName));        } catch (IOException e) {            throw new AdqRuntimeException("error on getResult" ,e);        } catch (ClassNotFoundException e) {            throw new AdqRuntimeException("error on getResult" ,e);        }        return object;    }

就能正确反序列化了

 

转载于:https://www.cnblogs.com/alway-july/p/8398842.html

你可能感兴趣的文章
Git-git提交报错error:RPC failed
查看>>
mysql-mysqlslap执行报错
查看>>
sdn
查看>>
# 2017-2018-1 20155302 课下实践IPC及课上补充
查看>>
java8新特性之Optional类
查看>>
在Qt(C++)中使用QThread实现多线程
查看>>
11-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案微信小程序篇(微信配网配置_Airkiss步骤_2)...
查看>>
jquery阅读记录2
查看>>
zabbix电话告警V1
查看>>
eclipse把局部变量提为全局变量的快捷键是什么
查看>>
《研磨设计模式》——可配置的简单工厂
查看>>
为网站添加免费的访问计数统计和加入微博
查看>>
ubuntu root用户 默认密码
查看>>
对百度搜索法的分析评价
查看>>
网络知识之ipset
查看>>
Credit Memo和Debit Memo在AR以及AP中的概念比较
查看>>
在Azure上部署Sqlserver网络访问不了的问题
查看>>
hdu 1561 The more, The Better(树形dp入门)
查看>>
最小度限制生成树模板
查看>>
树状数组总结
查看>>