构造ObjectInputStream时出现EOFException

时间:2012-09-18 13:37:44

标签: java android java-ee

我正在尝试在服务器端(Tomcat 6.0.29)上序列化HashMap并在客户端Android应用程序上对其进行deserealize。

我第一次尝试这个时遇到了StreamCorruptedException,但是在我创建了一个带有干净的doGet / doPost-Method的完全新的servlet后,我设法解决了这个问题,不幸的是我得到了一个EOFException。

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

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

    if ("object".equals(request.getParameter("format")))
        {

            trace.log("Before Serializing");
            ObjectOutputStream out = null;
            try
            {
                out = new ObjectOutputStream(response.getOutputStream());
                out.writeObject(outerTable);
                trace.log("after Serializing");
            }
            finally
            {
                if(out != null)
                {
                    try
                    {
                        out.flush();
                        out.close();
                    }
                    catch(Exception ex)
                    {
                        trace.log("Exception has been thrown "+ex.getMessage());
                    }
                }
            }
            trace.log("after closing stream");
        }
        else
        {
            PrintWriter out = response.getWriter();
            out.println(outerTable.toString());
        }

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

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

Android-Application脚本(此方法在按下特定按钮后执行http请求):

    private synchronized void performNetworkAccess()
    {
  Runnable run = new Runnable()
  {
    @Override
    public void run()
    {
    System.out.println("in run()-Method");
    ObjectInputStream objInput = null;
    try
    {
        URL url = new URL(myWebsite);
        URLConnection con = url.openConnection();
        InputStream in = con.getInputStream(); 
        objInput = new ObjectInputStream(in);

        outerTable = (HashMap<String, HashMap<String, Object>>)              objInput.readObject();
        synchronized (monitor)
        {
        monitor.notifyAll();
        }
    }
    catch (Exception ex)
    {
        ex.printStackTrace();
    }
    finally
    {
        if (objInput != null)
        {
        try
        {
            objInput.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        }
    }

    }

};
Thread t1 = new Thread(run);
t1.start();
}

在调用ObjectInputStream类的构造函数之后立即发生异常。

堆栈跟踪:

  • W / System.err(1797):java.io.EOFException
  • W / System.err(1797):at libcore.io.Streams.readFully(Streams.java:83)
  • W / System.err(1797):at java.io.DataInputStream.readShort(DataInputStream.java:169)
  • W / System.err(1797):at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:2102)<< li>
  • W / System.err(1797):at java.io.ObjectInputStream。(ObjectInputStream.java:372)<< li>
  • W / System.err(1797):at de.tesla.jtheseuscontactsync.ContactSync $ 4.run(ContactSync.java:602)
  • W / System.err(1797):at java.lang.Thread.run(Thread.java:856)<< li>

我已经发现了很多这个问题,但我没有看到其中一个在调用readObject()之前发生此错误。

我已经尝试过的事情:

  • 在构建ObjectOutputStream后立即添加.flush()
  • 删除out.flush()和/或out.close()方法
  • 使用BufferedInput包装Input- / OutputStream - / - OutputStream
  • 将流检索为文件并尝试取消实现文件

奇怪的是当我第一次通过FileOutputStream将Object写入文件并通过Url.openStream()从客户端访问此文件(在服务器上)时,ObjectOutputStream可以完美地读取此对象,不幸的是这意味着很多当多个用户同时尝试检索此对象时出现问题...

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

1 个答案:

答案 0 :(得分:-2)

一些疯狂的想法...尝试在您的回复中添加Content-Length标题。可能意味着将你的字节写入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序列化

@Robert评论是对的。 Java序列化不是用于不同环境之间的通信。如果您在JVM和Dalvik之间工作,那就更多了。所以另一个框架会更合适(使用XML或JSON的东西可能很好,甚至用GZip [] Stream包装它。)