繁体   English   中英

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

[英]invalid stream header during java byte deserialization from sql server

我需要在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)

在表中,我保存在列类型-> 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)

怎么了?

让我们从“标题” 5B424065

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

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

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

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

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

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

那么它是从哪里来的呢?

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

正确的方法是什么?

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM