PUTting an URL

Today, somebody at work wanted to PUT some data to an URL. It’s part of an internal web service we use. Should be easy write. In Perl, it’s pretty trivial.

my $ua = LWP::UserAgent->new();
my $req = PUT 'http://example.com/dest', Content => $ARGV[0];
my $resp = $ua->request( $req );
die $resp->status_line, "\n" unless $resp->is_success;

That takes the first command line argument and PUTs it http://example.com/dest. Pretty simple stuff. But compare this to the Java way, which is what my colleague was attempting.

public class HttpPutTest {
    public static void main(String[] args) throws IOException {
        URL dest = new URL("http://example.com/dest");
        HttpURLConnection conn = (HttpURLConnection) dest.openConnection();
        if (conn.getResponseCode() < 200 || conn.getResponseCode() > 299)
            throw new IOException(conn.getResponseMessage());

Firstly, as with all Java, the sheer verbosity is staggering. But there are two things of interest to me here.

  1. The request and response are conflated into one object, an UrlConnection (or variation thereof). There’s no way to retrieve header values on the request once they’ve been set.
  2. Setting the content is done through the most contorted route. Firstly, we have to tell the connection that it’s to expect output (why? I’m doing output things below, it should work it out). Secondly, we have to fetch an OutputStream, marshal our input into bytes and then write those bytes to the stream.

It’s that OutputStream that gets me. Oh, I can see why you’d need it occasionally. But 90% of the time when you’re doing a PUT or a POST, the amount of data is tiny, and you have it all up front. So you don’t need to stream it to the server. You’re paying the price for it 100% of the time, even though it’s only needed 1% of the time, if that. Really, how hard would a setContent() method be?

Comments are Closed