views:

405

answers:

3

I am reading and write XML over a TCP connection (not HTTP) as part of a web service I'm developing, and I was wondering whether there is a more "springified" way (or even other ideas) of achieving what I'm trying below:

    InputStream is = null;
    OutputStream os = null;
    Socket s = null;
    try {
        s = new Socket(address, portNo);
        os = s.getOutputStream();
        os.write(msg.getBytes());
        os.flush();
        is = s.getInputStream();
        String xml = IOUtils.toString(is);
        return xml;
    } finally {
        IOUtils.closeQuietly(os);
        IOUtils.closeQuietly(is);
        if (s != null) s.close();
    }

Note, I've got no control over the server, so I don't think I'll be able to use Spring remoting, but was wondering whether this can be improved akin to spring's JdbcTemplates.

EDIT:

Note, just to clarify IOUtils is Apache commons-io...

A: 

Most of the Spring Technologies are based around standard approaches to doing things. TCP/IP is lower level than most applications need to deal with today. I can't remember the last time I wrote a line of code that used the Socket library directly. Instead, what is typically done is to build on top of a higher level protocol.

Using HTTP or RMI as a starting point would save a lot of hassle at the socket level. There are tons of good web services libraries to abstract the socket details away from the user. I would recommend using JAX-WS. Spring has an implementation of JAX-WS in their Spring-WS project. Apache CXF also allows configuration of web services through Spring.

RMI is also an option. Spring's remoting abstracts the RMI protocol away from your code allowing you to focus on the functionality. It does not give you access to the Sockets but that is probably not what you want to do anyway.

Chris Dail
As I said, I've got no control over the server part, as I'm connecting to a legacy system that does not use HTTP or web services or RMI just XML over TCP (legacy is so much fun...)Having said that these are good suggestions for the general case, but not quite applicable here.
beny23
+1  A: 

The "Spring approach" applies here not to how you do the TCP socket communications but how the classes that colloborate with this class interact with it.

So I think the "Spring approach" would be to hide any sort of socket communication behind a MessageSender (horrible name, I know) interface so that the collaborator classes only have to deal with a MessageSender and remain blind to the fact that any sort of low-level socket communication is going on to achieve the sending of that message.

matt b
The "approach" he's referring to is the pattern used by `JdbcTemplate`, `JndiTemplate`, `HibernateTemplate`, and so on. These have nothing to do with IoC, and everything to do with resource management (e.g. stream/session/connection handling).
skaffman
+1  A: 

Take a look at WebServiceTemplate. That is the main abstraction Spring provides for client-side web service access. Even though your server is not a typical web service, as long as it uses the same request-response pattern, you may still be able to use that as the basis for your solution. The class provides hooks for just about every part of the communication (marshalling, sending the request, receiving the response, unmarshalling, etc.). The JavaDoc lists all the steps it takes to perform web service calls and you can override pretty much anything there. So, for example, you can use the built-in marshalling support, but override createConnection to build your custom TCP connection.

Rob H
That looks an interesting way forward. Not 100% sure whether this wouldn't end up being a more complex solution than the code above, but it looks like an option. Thanks.
beny23