Ayobami Opeyemi
Ayobami Opeyemi

Reputation: 752

what is the best way to send xml string over java Sockets?

I tried this, but somewhere along the line I can't read the response from the server. (The response is in XML).

I have read that writing over sockets requires buffering due to the string breakage. Somehow I discovered this is true when I used a jaxb unmarshaller and it reported a SAX EOF exception, meaning the xml been read was not complete.

Please how do I buffer write and buffer read properly?

StringBuilder sb = new StringBuilder();
sb.append("<estel>");
sb.append("<header><requesttype>").append(hd.getRequestType()).append("</requesttype></header>");
sb.append("<request>");
sb.append("<agentcode>").append(rq.getAgentCode()).append("</agentcode>");
sb.append("<pin>").append(rq.getPin()).append("</pin>");
sb.append("<destination>").append(rq.getDestination()).append("</destination>");
sb.append("<agenttransid>").append(rq.getAgentTransId()).append("</agenttransid>");
sb.append("<vendorcode>").append(rq.getVendorCode()).append("</vendorcode>");
sb.append("<amount>").append(rq.getAmount()).append("</amount>");
    sb.append("<productcode>").append(rq.getProductCode()).append("</productcode>");
    sb.append("<comments>").append(rq.getComments()).append("</comments>");
    sb.append("<clienttype>").append(rq.getClientType()).append("</clienttype>");
sb.append("</request></estel>");


    Socket socket = new Socket("41.206.23.21",7101);
    OutputStream os = socket.getOutputStream();
    InputStream in = socket.getInputStream();

    OutputStream buf = new BufferedOutputStream(os);    
    out = new OutputStreamWriter(buf);

    System.out.printf("\nxml is %s",sb.toString());   
   System.out.print("\n--------writing--to--socket-----");
    out.write(sb.toString());
    out.flush();

    //read response
    InputStream bui = new BufferedInputStream(in);
  rd = new InputStreamReader(bui);
   System.out.print("\nxml response"+rd.toString());

   in.close();
   out.close();
   socket.close();

Upvotes: 0

Views: 9059

Answers (2)

Matthias
Matthias

Reputation: 3592

Please reduce your issue to a running piece of code that shows the error. Posting some code that does not even compile, does not really help in understanding the problem you have. Even after fitting this code in a method and importing java.io stuff, there is 4 (!) undeclared variables: hd, rq, out and rd.

To help with your problem and answer your questions:

  1. You do not need to use a buffered writer, you just have to make sure you write everything you want to write (and flush or close the stream afterwards). The client (receiver) of course has to read from that stream as long as bytes are available before he tries to interpret the data.

  2. If you want to implement a different protocol, you of course have to read / write until a certain marker or whatever indicates that your transmission is finished. For this question however I assume you only want to transmit one set of XML data.

For writing you can simply write the String in one go using a simple OutputStream. Code like this would do the job:

StringBuilder sb = new StringBuilder();
//...
Socket socket = new Socket("41.206.23.21", 7101);
OutputStream os = socket.getOutputStream();
os.write(sb.toString().getBytes());
os.flush();

Reading that, you can also use a simple InputStream. To make sure you get everything, you should usually read the data and write it all to an intermediate byte array which you then can transform back into your String. A generic method for doing that, could be like this:

  String read(InputStream in) throws IOException {
    byte[] buffer = new byte[8192];
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    int got;
    while ((got = in.read(buffer)) > -1) {
      out.write(buffer, 0, got);
    }
    byte[] data = out.toByteArray();
    String result = new String(data);
    return result;
  }

Keep in mind that this method neither closes the stream, nor handles exceptions.

Upvotes: 0

jboi
jboi

Reputation: 11912

You send the XML over the socket but the server side does not answer. To be 100% sure what happens, we would need the server code and server error messages. So far I see two things, you could do:

  1. When writing and flushing the XML, you can call socket.shutdownOutput(). This sends an EOF to the server, indicating that there's nothing more to read. Latest than the server should know, that it has to work on the XML and produce the result.

  2. You send a String of char over a Stream of byte. Hopefully the server understands that in the same way as the client sends it. As hope is not really helpful in programming, you should wrap the output stream like this: Writer writer = new OutputStreamWriter(socket.shutdownOutput(), "UTF-8"); and do the write and the flush with the writer. Notice that you need to do the same on the server side for the input stream (wrap as Reader with "UTF-8")

Upvotes: 0

Related Questions