Java 构造ObjectInputStream时的EOFEException

Java 构造ObjectInputStream时的EOFEException,java,android,jakarta-ee,Java,Android,Jakarta Ee,我试图在服务器端(Tomcat6.0.29)序列化HashMap,并在客户端android应用程序上反序列化它 第一次尝试这个方法时,我得到了一个StreamCorruptedException,但在使用干净的doGet/doPost方法创建了一个全新的servlet之后,我成功地解决了这个问题,不幸的是,我得到了一个EOFException 因此,首先我发布我的代码,然后我将详细解释我的问题: 服务器端代码(调用doPost或doGet时将执行此代码): outerTable是一个HashMa

我试图在服务器端(Tomcat6.0.29)序列化HashMap,并在客户端android应用程序上反序列化它

第一次尝试这个方法时,我得到了一个StreamCorruptedException,但在使用干净的doGet/doPost方法创建了一个全新的servlet之后,我成功地解决了这个问题,不幸的是,我得到了一个EOFException

因此,首先我发布我的代码,然后我将详细解释我的问题:

服务器端代码(调用doPost或doGet时将执行此代码):

outerTable是一个HashMap,它恰好创建在此代码块之前,并且始终具有正确的值

服务器端没有抛出错误。 当我尝试使用参数“?format=object”访问webbrowser中的servlet时,我得到 整个序列化字符串

Android应用程序脚本(此方法在按下特定按钮后执行http请求):

private synchronized void performNetworkAccess()
{
Runnable run=new Runnable()
{
@凌驾
公开募捐
{
System.out.println(“in run()-Method”);
ObjectInputStream objInput=null;
尝试
{
URL=新URL(我的网站);
URLConnection con=url.openConnection();
InputStream in=con.getInputStream();
objInput=新对象输入流(in);
outerTable=(HashMap)objInput.readObject();
同步(监视器)
{
monitor.notifyAll();
}
}
捕获(例外情况除外)
{
例如printStackTrace();
}
最后
{
if(objInput!=null)
{
尝试
{
objInput.close();
}
捕获(IOE异常)
{
e、 printStackTrace();
}
}
}
}
};
线程t1=新线程(运行);
t1.start();
}
调用ObjectInputStream类的构造函数后立即发生异常

堆栈跟踪:

  • W/System.err(1797):java.io.EOFException
  • W/System.err(1797):位于libcore.io.Streams.readfull(Streams.java:83)
  • W/System.err(1797):位于java.io.DataInputStream.readShort(DataInputStream.java:169)
  • W/System.err(1797):位于java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:2102)
  • W/System.err(1797):位于java.io.ObjectInputStream。(ObjectInputStream.java:372)
  • W/System.err(1797):位于de.tesla.jtheseuscontactsync.ContactSync$4.run(ContactSync.java:602)
  • W/System.err(1797):位于java.lang.Thread.run(Thread.java:856)
我已经发现了许多此类问题,但在调用readObject()之前,我没有看到其中一个出现此错误

我已经尝试过的事情:

  • 在构造ObjectOutputStream后不久,add out.flush()
  • remove out.flush()和/或out.close()方法
  • 使用BufferedInput-/-OutputStream包装输入-/OutputStream
  • 将流检索为文件并尝试反序列化该文件
奇怪的是,当我第一次通过FileOutputStream将对象写入一个文件,并通过Url.openStream()从客户端访问该文件(在服务器上)时,ObjectOutputStream可以完美地读取该对象,不幸的是,当多个用户试图同时检索该对象时,这将意味着很多麻烦


我希望你能帮我解决这个问题:)

一些疯狂的想法。。。尝试将
内容长度
标题添加到响应中。可能意味着将字节写入ByteArrayOutputStream,测量大小,设置标头,然后才写入响应。。。但这可能是URLConnection过早切断连接的原因

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObejctOutputStream oos = new ObejctOutputStream(baos);
oos.write(...);

byte[] data = baos.toByteArray();

response.setHeader("Content-Length", "" + data.length);
response.getOutputStream().write(data);
Java序列化


@罗伯特的评论是对的。Java序列化并不用于不同环境之间的通信。如果您在JVM和Dalvik之间工作,则需要更多。因此,另一个框架更合适(使用XML或JSON的东西可能很好,甚至可以用GZip[]流包装它)。

一些疯狂的想法。。。尝试将
内容长度
标题添加到响应中。可能意味着将字节写入ByteArrayOutputStream,测量大小,设置标头,然后才写入响应。。。但这可能是URLConnection过早切断连接的原因

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObejctOutputStream oos = new ObejctOutputStream(baos);
oos.write(...);

byte[] data = baos.toByteArray();

response.setHeader("Content-Length", "" + data.length);
response.getOutputStream().write(data);
Java序列化


@罗伯特的评论是对的。Java序列化并不用于不同环境之间的通信。如果您在JVM和Dalvik之间工作,则需要更多。因此,另一个框架更合适(使用XML或JSON的东西可能很好,甚至可以用GZip[]流包装它)。

servlet遇到了某种异常,甚至没有构造ObjectOutputStream。在客户端尝试构造ObjectInputStream之前,需要检查响应代码是否为200。

servlet出现了某种异常,甚至还没有构造ObjectOutputStream。在客户端尝试构造ObjectInputStream之前,需要检查200的响应代码。

由ObjectOutputStream创建的序列化Java对象只能在使用相同实现的环境中反序列化。即使更改JRE版本也会阻止反序列化。因此,使用序列化在复杂的非自写对象结构中传输数据是一个非常糟糕的主意。事实上,我本打算回答这个问题,但我看到反序列化在从文件完成时起作用。。。所以我改了帖子:)@Robert,这是完全错误的。Java序列化机制与所有JRE都兼容,可以追溯到Java 1.1。@EJP该机制定义良好,但不是属于JRE的类。序列化包含Java API中从未描述过的私有字段上的数据,因此序列化可能会失败,特别是在使用不同的Java运行时环境(例如
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObejctOutputStream oos = new ObejctOutputStream(baos);
oos.write(...);

byte[] data = baos.toByteArray();

response.setHeader("Content-Length", "" + data.length);
response.getOutputStream().write(data);