我正在尝试在服务器端(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 可以完美地读取该对象,不幸的是,这意味着很多麻烦多个用户试图同时检索此对象...
我希望你能帮我解决这个问题:)