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.