java伪装反序列化字节流_从SQL Server反序列化Java字节期间无效的流头

我需要在SQL Server 2008表中保存序列化的对象流,然后反序列化它。 当我反序列化时出现问题。我得到以下异常:

Exception in thread"main" java.io.StreamCorruptedException: invalid stream header: 5B424065

at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:804)

at java.io.ObjectInputStream.(ObjectInputStream.java:299)

我使用的是JTDS-1.2.4(不是最后一个JTDS驱动程序类型4)

在表中,我保存在列类型-> NVARCHAR(MAX)中,例如

[B @ e3fd79

我读了上面的值(jtds给我一个sql.Clob),我尝试反序列化它

我的Java代码:

DocumentObjectHolder doc = new DocumentObjectHolder(xmldata,"data.xml", TYPE.XML, xmldata.getBytes("UTF-8"));

//SERIALIZE DocumentObjectHolder

ByteArrayOutputStream bof = new ByteArrayOutputStream();

ObjectOutputStream serialize = new ObjectOutputStream(bof);

serialize.writeObject(doc);

SQLDbManagerFactory.setDbConnectionParameters(dbUri, username, password, driver);

SQLDBManager factoryDb = SQLDbManagerFactory.getSQLDBManager();

factoryDb.execSQL("INSERT INTO MY_DOCUMENTS (DATA,DOCUMENT_TYPE,IS_READY,DO_EMIT,IS_EMITTED)" +

" VALUES ( '" + bof.toByteArray() +"','" + TYPE.XML.name() +"', 0, 0, 0)");

RecordSet rs = (RecordSet) factoryDb.execSQL("SELECT TOP 1 DATA FROM MY_DOCUMENTS");

if (rs != null && rs.getLength() > 0){

//DESERIALIZE in DocumentObjectHolder

Clob objris = (Clob)rs.get(0, 0);

InputStream in = objris.getAsciiStream();

byte[] b = new byte[in.available()];

in.read(b);

ByteArrayInputStream bais = new ByteArrayInputStream(b);

ObjectInputStream ins = new ObjectInputStream(bais);

DocumentObjectHolder mc =(DocumentObjectHolder)ins.readObject();

System.out.println("Object in value ::"+mc.toString());

ins.close();

in.close();

}

SQLDBManager是我的私有库。

我想这将是一个Blob(字节blob)而不是Clob(char lob),所以我尝试将nvarchar(max)更改为varbinary(500),因为我在这里阅读:

http://jtds.sourceforge.net/typemap.html

但我得到以下异常:

Exception in thread"main" java.sql.SQLException: Invalid SQL statement or JDBC escape, terminating ']' not found.

at net.sourceforge.jtds.jdbc.SQLParser.parse(SQLParser.java:1155)

at net.sourceforge.jtds.jdbc.SQLParser.parse(SQLParser.java:156)

at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.(JtdsPreparedStatement.java:107)

at net.sourceforge.jtds.jdbc.ConnectionJDBC2.prepareStatement(ConnectionJDBC2.java:2456)

at net.sourceforge.jtds.jdbc.ConnectionJDBC2.prepareStatement(ConnectionJDBC2.java:2414)

怎么了?

让我们从"标题" 5B424065开始。

如果将其转换为ASCII,则会得到'[' 'B' '@' 'e' ...看起来很熟悉吗?

现在,您的字符串"[B@e3fd79"。它是什么?

首先,它不是有效的序列化。实际上,这就是在byte[]上调用toString()时得到的。

"[B"组件是byte[]的类型签名。

"e3fd79"组件是一个身份哈希码...通常在首次请求身份哈希码时基于数组地址。

最重要的是,此字符串未对字节数组的内容进行编码/

那么它是从哪里来的呢?

它来自以下表达式:bof.toByteArray()。这不是将字节数组的内容转换为字符串的正确方法。

正确的方法是什么?

它取决于" DATA"列的SQL类型。是的-@EJP很特别。您根本不应该尝试对字节数组进行字符串化。使用PreparedStatement和参数占位符(?)。

如果列类型为BINARY或VARBINARY,则您应该能够按原样传递byte[]。有关jDTS类型映射的完整列表,请参考文档。

数据是nvarchar(max),然后我更改为varbinary,然后尝试二进制,但是得到了相同的DataTruncated Ex。所以使用toByteArray()出错,因为它写入了字符串字节或错误的sql数据类型?

也许我必须像本文中那样使用字符串而不是字节? -> stackoverflow.com/questions/134492/

@ robyp7您根本不应该将字节数组转换为字符串。 您应该将PreparedStatement与?一起使用。 标记。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值