2

I need to call a servlet call for an automation of a java applet using c#. What the java applet is it calls a servlet using a URL Connection object.

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();

The problem is i need to simulate this using c#. I believe the counterpart object would be 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();

How do I write the string as a serialized java string? Is there any workaround here? According to the documentation of ObjectOutputStream in java, it serialize the object except for primitive type. I know String is class, so does it serialzie it like an object or some special case?

I have tried one solution, I have imported the IKVM (http://www.ikvm.net/) java virtual machine in my reference and am trying to use the java.io library in Java. Unforunately, when the ObjectInputStream constructor is called, a "invalid stream header" is thrown.

Here is my altered code:

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)
Nap
  • 8,096
  • 13
  • 74
  • 117

2 Answers2

2

I finally got to get this to work.

The problem is on reading the data in .NET instead of using StreamReader, I need to use the Stream object immediately. Anyway just leaving it here in case it helps others with their problem:

Wrong Code:

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

Correct Code:

byte[] buffer = new byte[1000];
using (Stream sr = myRequest.GetResponse().GetResponseStream())
{
    sr.Read(buffer, 0, 1000);
}
Nap
  • 8,096
  • 13
  • 74
  • 117
1

If you have control over the serialization/deserialization on the Java side, your best bet is to use a cross-platform serialization protocol such as Protocol Buffers. For C++, Java, and Python:

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

For .NET, Jon Skeet wrote a port:

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

James Kovacs
  • 11,549
  • 40
  • 44
  • Thanks for the interopt. But unfortunately the java servlet is a third party and I need this for automation of task. – Nap Dec 21 '10 at 05:07
  • In that case, you're stuck trying to recreate the Java object serialization format in C#. Not a fun task. Does the servlet provide no other input options, such as JSON, XML, etc.? Given that you don't need to serialize all types of data, you might just want to craft up a small piece of Java to feed the data, sniff the traffic with WireShark, and then emulate that in your C#... – James Kovacs Dec 21 '10 at 05:16
  • I am actually trying to use the IKVM (http://www.ikvm.net/) dot net virtual machine so I can use java functions in my C# code. But after reading the input stream, it always says InvalidStreamHeader when I use java.io.ObjectInputStream. I will update my comment up to show my suggested solution to see if others were able to do the task. – Nap Dec 21 '10 at 05:29
  • Also, on your first question, there are no other output option for the servlet. I am trying to simulate what a java applet does for a task automation. So probably the applet have no problem with the ObjectOutputStream reconvertion. – Nap Dec 21 '10 at 05:30
  • IKVM (or similar) could work. Basically some 3rd-party library to take on the heavy-lifting of mimicking the Java behaviour. Not sure why you're getting an invalid stream exception. I think your best bet - since it appears that you've got a very limited set of inputs you need to replicate - is to use WireShark to sniff traffic and then just replicate the bytestream using .NET. – James Kovacs Dec 21 '10 at 06:10
  • Thanks James, I already got it to work. And, I found the cause of the Stream exception, basically I used StreamReader object which reads only text data. I need to use Steam object so I can read the serialized Java strings in c# properly. Yes, I actually used fiddler and wireshark with this one. Thanks for the help. – Nap Dec 24 '10 at 00:40