A major goal of the Stringtree software project has always been to be as compatible as possible with all the software people are using for their Java development. Naturally that also includes whatever Java version is being used.
For a long time I interpreted this goal as implying that all Stringtree code should run on all Java versions from Java 1.2 onwards. Java 1.4, however, introduced some compelling new features including built-in regular-expression handling. For a few years I still tried to ensure that most code was still 1.2-compatible (for example by using Ant to swap in a third-party regular-expression library while building a jar file), while also providing a Java 1.4 version. Eventually, use of Java versions prior to 1.4 declined enough that I felt comfortable removing the complicated pre-1.4 version.
For the last few years I have been very careful to keep all my Stringtree code compatible with all versions of Java from 1.4 upwards. Now, however, the pressure is building again to move over to Java 5. In my day-to-day coding I develop with Java 5 and make increasing use of Java 5 features such as the enhanced for loop, the Iterable interface, enums, generics, autoboxing, varargs and so on. It would be very nice to be able to update the Stringtree codebase to use these features too.
Occasionally a Java 5-specific detail has crept in to a Stringtree library, and I have soon received comments or emails pointing this out. I haven’t noticed this for a while, which might indicate either that I have been especially careful, or that I there are no longer any/many people developing with Stringtree code who are still limited to Java 1.4.
If you are reading this and you still require Java 1.4 support, please let me know. Likewise, if you have thrown off the shackles of 1.4 within the last year or so or are desperately hoping for a Java 5 Stringtree that would be good to know too.
Is it time for Java 5 yet?
Posted by Stringtree as Friki, General, HTTPClient, Inkling, JSON, Mojasef, Projects, Templater at 7:59 PM PDT
No Comments »
This post is the first of a series describing the use and implementation of the Stringtree HTTP Client.
Recently I have been working with systems which talk to each other using REST/HTTP. Providing services and resources is pretty simple using Mojasef, but accessing such resources and consuming such services (in client code and in tests) has always seemed a bit more clumsy than it should be. I tried Apache HTTPClient and HttpUnit, but both seemed cumbersome for simple tasks, and bring in several hundred KB or more of dependencies, which can really bloat a small client application. I’m sure there are others, but I got bored with looking, and instead wrote my own simple HTTP Client which does the things I need without dragging in tons of extra stuff.
The Stringtree HTTP Client consists of just four classes, with no dependencies other than the standard Java APIs:
The point of these classes is to allow simple construction and calling of all valid HTTP requests, including the ability to set and read headers and cookies, simulate the submission of an HTML form, and support both textual and binary content data.
As a very simple example, consider the following code which issues a GET request to a specified URL:
HTTPClient client = new HTTPClient();
Document response = client.get("http://localhost:8080/?a=b");
System.out.println("response content type=" + response.getHeader("Content-Type"));
System.out.println("response content=" + response.getContentAsString());
The above code example shows basic usage of the Stringtree HTTP Client. In more general terms, usage is as follows:
- Create an object of the HTTPClient class.
- Set any long-lived settings, such as cookies or a user-agent.
- Call one of the request methods with appropriate parameters.
- Read returned headers and content as required from the returned Document object.
- Repeat from (3) for each new request.
A slightly more complex example using a POST request to submit an HTML form might look like:
HTTPClient client = new HTTPClient("Mozilla/5.0 (example)");
client.setCookie("username", "Frank");
Form form = new Form();
form.put("name", "Widget");
form.put("category", "thing");
Document response = client.post("http://localhost:8080/update", form);
boolean ok = "200".equals(response.getHeader(HTTPClient.HTTP_RESPONSE_CODE));
All the request methods return an org.stringtree.http.Document object. This object represents the structure of an HTTP request or response: a collection of name/value headers (which may contain duplicate names), and a block of “content” which may be considered as text or as a sequence of bytes. The HTTPClient code does make one simplifying concession; as seen in the above POST example the HTTP response code is added as a pseudo-header with the name “http.response.code”.
This should be enough to get started playing with the Stringtree HTTP Client. In the next post I will discuss the possibilities for creating and configuring an HTTPClient object in full detail.
Posted by Stringtree as HTTPClient, Projects at 11:00 AM PST
No Comments »