【问题标题】:How can you emulate object serialization on java in C#如何在 C# 中模拟 java 上的对象序列化
【发布时间】:2010-12-21 04:05:52
【问题描述】:

我需要调用一个 servlet 调用,以便使用 c# 实现 Java 小程序的自动化。 java applet 是什么,它使用 URL Connection 对象调用 servlet。

URL servlet = new URL(servletProtocol, servletHost, servletPort, "/" + ServletName);
URLConnection con = servlet.openConnection();
con.setDoOutput(true);
ObjectOutputStream out = new ObjectOutputStream(con.getOutputStream());
// Write several parameters strings
out.writeObject(param[0]);
out.writeObject(param[1]);
out.flush();
out.close();

问题是我需要使用 c# 来模拟这个。我相信对应的对象是 HttpWebRequest

HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(servletPath);
myRequest.Method = "POST";
myRequest.ContentType="application/x-www-form-urlencoded";
myRequest.ContentLength = data.Length;
Stream newStream=myRequest.GetRequestStream();
// Send the data.
newStream.Write(param[0],0,param[0].length);
newStream.Write(param[1],0,param[1].length);
newStream.Close();

如何将字符串写成序列化的 java 字符串?这里有什么解决方法吗?根据java中ObjectOutputStream的文档,它序列化了除原始类型之外的对象。我知道 String 是类,那么它是像对象还是某些特殊情况一样序列化它?

我尝试了一种解决方案,我在参考中导入了 IKVM (http://www.ikvm.net/) java 虚拟机,并尝试在 Java 中使用 java.io 库。不幸的是,当调用 ObjectInputStream 构造函数时,会抛出“无效的流标头”。

这是我修改后的代码:

myRequest.Method = "POST";
myRequest.ContentType = "application/x-www-form-urlencoded";
myRequest.ContentLength = data.Length;
Stream newStream = myRequest.GetRequestStream();

// Send the data.
newStream.Write(data, 0, data.Length);
newStream.Close();

List<byte> lByte = new List<byte>();
using (StreamReader sr = new StreamReader(myRequest.GetResponse().GetResponseStream()))
{
    while (sr.Peek() >= 0)
    {
        lByte.Add((byte)sr.Read());
    }
}

byte[] bArr = lByte.ToArray();
ObjectInputStream inputStream = null;

try
{
    //Construct the ObjectInputStream object
    inputStream = new ObjectInputStream(new ByteArrayInputStream(bArr));

    Object obj = null;

    while ((obj = inputStream.readObject()) != null)
    {
        string objStr = obj as string;
    }


}
catch (java.lang.Exception ex)

【问题讨论】:

    标签: c# java interop ikvm object-serialization


    【解决方案1】:

    如果您可以控制 Java 端的序列化/反序列化,最好的选择是使用跨平台序列化协议,例如 Protocol Buffers。对于 C++、Java 和 Python:

    http://code.google.com/p/protobuf/

    对于 .NET,Jon Skeet 写了一个移植:

    http://code.google.com/p/protobuf-net/

    【讨论】:

    • 感谢 interopt。但不幸的是,java servlet 是第三方,我需要它来自动化任务。
    • 在这种情况下,您将无法尝试在 C# 中重新创建 Java 对象序列化格式。不是一个有趣的任务。 servlet 是否不提供其他输入选项,例如 JSON、XML 等?鉴于您不需要序列化所有类型的数据,您可能只想制作一小段 Java 来提供数据,使用 WireShark 嗅探流量,然后在您的 C# 中进行模拟...
    • 我实际上是在尝试使用 IKVM (ikvm.net) 点网虚拟机,这样我就可以在我的 C# 代码中使用 java 函数。但是在读取输入流之后,当我使用 java.io.ObjectInputStream 时它总是说 InvalidStreamHeader。我将更新我的评论以显示我建议的解决方案,看看其他人是否能够完成这项任务。
    • 另外,关于您的第一个问题,servlet 没有其他输出选项。我正在尝试模拟 java 小程序对任务自动化的作用。所以可能小程序对 ObjectOutputStream 的重新转换没有问题。
    • IKVM(或类似的)可以工作。基本上是一些第 3 方库来承担模仿 Java 行为的重任。不知道为什么您会收到无效的流异常。我认为你最好的选择——因为看起来你需要复制的输入非常有限——是使用 WireShark 来嗅探流量,然后使用 .NET 复制字节流。
    【解决方案2】:

    我终于得到了这个工作。

    问题在于在 .NET 中读取数据而不是使用 StreamReader,我需要立即使用 Stream 对象。无论如何,只要把它留在这里,以防它帮助其他人解决他们的问题:

    错误代码:

    List<byte> lByte = new List<byte>();
    using (StreamReader sr = new StreamReader(myRequest.GetResponse().GetResponseStream()))
    {
        while (sr.Peek() >= 0)
        {
            lByte.Add((byte)sr.Read());
        }
    }
    

    正确代码:

    byte[] buffer = new byte[1000];
    using (Stream sr = myRequest.GetResponse().GetResponseStream())
    {
        sr.Read(buffer, 0, 1000);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-12
      • 1970-01-01
      • 2021-04-22
      • 2010-10-06
      • 2023-03-03
      • 2017-09-13
      • 2011-05-21
      相关资源
      最近更新 更多