2

我正在尝试在服务器端(Tomcat 6.0.29)序列化 HashMap 并在客户端 android 应用程序上取消实现它。

我第一次尝试这个时,我得到了一个 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”访问我的网络浏览器中的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):在 libcore.io.Streams.readFully(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 后不久添加 out.flush()
  • 删除 out.flush() 和/或 out.close() 方法
  • 用 BufferedInput-/-OutputStream 包装 Input-/OutputStream
  • 将流作为文件检索并尝试取消实现该文件

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

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

4

2 回答 2

0

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

于 2012-09-18T21:55:37.563 回答
-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 包装它)。

于 2012-09-18T13:54:25.737 回答