我需要在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.<init>(ObjectInputStream.java:299)
我使用JTDS-1.2.4(不是最后一个JTDS驱动程序类型4)
在表格中,我保存在列类型中 - &gt; 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.<init>(JtdsPreparedStatement.java:107)
at net.sourceforge.jtds.jdbc.ConnectionJDBC2.prepareStatement(ConnectionJDBC2.java:2456)
at net.sourceforge.jtds.jdbc.ConnectionJDBC2.prepareStatement(ConnectionJDBC2.java:2414)
怎么了?
答案 0 :(得分:1)
让我们从“标题”5B424065
开始。
如果您将其翻译为ASCII,则会得到'['
'B'
'@'
'e'
...这看起来很熟悉吗?
现在是你的字符串"[B@e3fd79"
。它是什么?
首先,它不是有效的序列化。事实上,它是......当您在toString()
上致电byte[]
时获得的。
"[B"
组件是byte[]
的类型签名。
"e3fd79"
组件是一个标识哈希码...通常基于数组地址,在首次请求标识哈希码时。
最重要的是,此字符串不编码字节数组的内容/
那它来自哪里?
它来自这个表达:bof.toByteArray()
。这不是将字节数组的内容转换为字符串的正确方法。
正确的方法是什么?
这取决于“DATA”列的SQL类型。是的 - @EJP是现货。您根本不应该尝试对字节数组进行字符串化。使用PreparedStatement
参数占位符(?
)。
如果列类型是BINARY或VARBINARY,那么您应该能够按原样传递byte[]
。有关jDTS类型映射的完整列表,请参阅the documentation。