我正在尝试在服务器端(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类的构造函数之后立即发生异常。
堆栈跟踪:
我已经发现了很多这个问题,但我没有看到其中一个在调用readObject()之前发生此错误。
我已经尝试过的事情:
奇怪的是当我第一次通过FileOutputStream将Object写入文件并通过Url.openStream()从客户端访问此文件(在服务器上)时,ObjectOutputStream可以完美地读取此对象,不幸的是这意味着很多当多个用户同时尝试检索此对象时出现问题...
我希望你能帮我解决这个问题:)
答案 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包装它。)