HTTP is tiny, raw HTTP client - and yet simple and convenient. It offers a simple way to send requests and read responses - so to please developers.

The best way to learn about HTTP is through examples.

Simple GET

    HttpRequest httpRequest = HttpRequest.get("");
    HttpResponse response = httpRequest.send();


All HTTP classes offers fluent interface, so you can write:

    HttpResponse response = HttpRequest.get("").send();


You can build the request step by step:

    HttpRequest request = new HttpRequest();

Reading response

When HTTP request is sent, the whole response is stored in HttpResponse instance. You can use response for various stuff. You can get the statusCode() or statusPhrase(); or any header attribute.

Most important thing is how to read received response body. You may use one of the following methods:

  • body() - raw body content, always in ISO-8859-1 encoding.
  • bodyText() - body text, i.e. string encoded as specified by Content-Type header.
  • bodyBytes() - returns raw body as byte array, so e.g. downloaded file can be saved.

Character encoding used in bodyText() is one set in the response headers. If response does not specify the encoding in it's headers (but e.g. only on the HTML page), you must specify the encoding with charset() method before calling bodyText().

Query parameters

Query parameters may be specified in the URL line (but then they have to be encoded correctly):

    HttpResponse response = HttpRequest

Better and recommended way is with the query() method:

    HttpResponse response = HttpRequest
        .query("userId", "10194")

You can use query() for each parameter, or pass many arguments in one call (varargs). You can also provide Map<String, String> as a parameter too.

Note: query parameters (as well as headers and form parameters) can be duplicated. Therefore, they are stored in an array internally. Use method removeQuery to remove some parameter, or overloaded method to replace parameter.

Finally, you can reach internal query map, that actually holds all parameters:

    Map<String, Object[]> httpParams = request.query();
    httpParams.put("userId", new String[] {"10194"});


Basic authentication is made easy:

    request.basicAuthentication("user", "password");

Token-based authentication:


POST and form parameters


    HttpResponse response = HttpRequest
        .form("userId", "10194")

Use form() in the same way as query() to specify form parameters. Everything what is said for query() applies to the form().

Upload files

Again, it's easy: just add file form parameter. Here is one real-world example:

    HttpRequest httpRequest = HttpRequest
            "repositoryId", "10178",
            "folderId", "11219",
            "sourceFileName", "",
            "mimeType", "application/zip",
            "title", "test",
            "description", "Upload test",
            "changeLog", "testing...",
            "file", new File("d:\\")

    HttpResponse httpResponse = httpRequest.send();

Monitor upload progress

When uploading large file, it is helpful to monitor the progress. For that purpose you can use HttpProgressListener like this:

    HttpResponse response = HttpRequest
        .form("file", file)
        .monitor(new HttpProgressListener() {
            public void transferred(long len) {

Before the upload starts, HttpProgressListener calculates the callbackSize - the size of chunk in bytes that will be transfered. By default, this size equals to 1% of total size. Moreover, it is never less then 512 bytes.

HttpProgressListener contains the inner field size with the total size of the request. Note that this is the size of whole request, not only the files! This is the actual number of bytes that is going to be send, and it is always a bit larger then file size (due to protocol overhead).


Add or reach header parameters with method header(). Some common header parameters are already defined as methods, so you will find contentType() etc.

There are some shortcut methods that are commonly used:

  • contentTypeJson() - specifies JSON content type
  • acceptJson() - accepts JSON content.

GZipped content

Just unzip() the response.

    HttpResponse response = HttpRequest


The unzip() method is safe; it will not fail if response is not zipped.

Set the body

You can set request body manually:

    HttpResponse response = HttpRequest
        .body("{'a':1 23, 'b': 'hi'}")
        .basicAuthentication("test", "test")

Setting the body discards all previously set form() parameters.

Charsets and Encodings

By default, query and form parameters are encoded in UTF-8. This can be changed globally in JoddHttp, or per instance:

    HttpResponse response = HttpRequest
        .query("param", "value")

You can set form encoding similarly. Moreover, form posting detects value of charset in "Content-Type" header, and if present, it will be used.

With received content, body() method always returns the raw string (encoded as ISO-8859-1). To get string in usable form, use method bodyText(). This method uses provided charset from "Content-Type" header and encodes the body string.

Following redirection

By default HttpRequest does not follow redirection response. This can be changed by setting the followRedirects(true). Now redirect responses are followed. When redirection is enabled, the original URL will NOT be preserved in the request object!

Asynchronous sending

When send() is called, the program blocks until the response is received. By using sendAsync() the execution of the sending is passed to Javas fork-join pool, and will be executed asynchronously. Method returns CompletableFuture<Response>.


Physical HTTP communication is encapsulated by HttpConnection interface. On send(), HTTP will open() connection if not already opened. Connections are created by the connection provider: HttpConnectionProvider. Default connection provider is socket-based and it always returns a new SocketHttpConnection instance - that simply wraps a Socket and opens it.

It is common to use custom HttpConnectionProvider, based on default implementation. For example, you may extend the SocketHttpConnectionProvider and override createSocket() method to return sockets from some pool, or sockets with different timeout.

Alternatively, you many even provide instance of HttpConnection directly, without any provider.


As said, default communication goes through the plain Socket. Since it is a common need to tweak socket behavior before sending data, here are two examples how you can do it with HTTP.


Since we know the default type of HttpConnection, we can simply get the instance after explicitly calling the open() and cast it:

    HttpRequest request = HttpRequest.get()...;;
    SocketHttpConnection httpConnection =
        (SocketHttpConnection) request.httpConnection();
    Socket socket = httpConnection.getSocket();
    HttpResponse response = request.send();


The other way is to use custom HttpConnectionProvider based on SocketHttpConnectionProvider. So you may create your own provider like this:

    public class MyConnectionProvider extends SocketHttpConnectionProvider {
        protected Socket createSocket(
                SocketFactory socketFactory, String host, int port)
                throws IOException {
            Socket socket = super.createSocket(socketFactory, host, port);
            return socket;

Now you can use this provider directly in open() method:

    HttpConnectionProvider connectionProvider = new MyConnectionProvider();
    HttpRequest request = HttpRequest.get()...;
    HttpResponse response =;

If you want your connection provider to be default one for all your communication, just assign it to the JoddHttp.httpConnectionProvider and you can avoid the explicit open() usage.


By default, all connections are marked as closed, to keep servers happy. HTTP allows usage of permanent connections through 'keep-alive' mode. The HttpConnection is opened on the first request and then re-used in communication session; the socked is not opened again if not needed and therefore it is reused for several requests.

There are several ways how to do this. The easiest way is the following:

    HttpRequest request = HttpRequest.get("");
    HttpResponse response = request.connectionKeepAlive(true).send();

    // next request
    request = HttpRequest.get("");
    response = request.keepAlive(response, true).send();


    // last request
    request = HttpRequest.get("");
    response = request.keepAlive(response, false).send();

    // optionally

This example fires several requests over the same HttpConnection (i.e. the same socket). When in 'keep-alive' mode, HTTP continues using the existing connection, while paying attention on servers responses. If server explicitly requires connection to be closed, HTTP will close it and then it will open a new connection to continue your session. You don't have to worry about this, just keep calling keepAlive() and it will magically do everything for you in the background. Just don't forget to pass false argument to the last call to indicate server that is the last connection and that we want to close after receiving the last response. (if for some reasons the server does not responds correctly, you may close communication on client side with an explicit call to response.close()). One more thing - if a new connection has to be opened during this persistent session (when e.g. keep-alive max counter is finished or timeout expired) the same connection provider will be used as for the initial, first connection.


HttpConnectionProvider also allows you to specify the proxy. Just provide the ProxyInfo instance with the information about the used proxy (type, address, port, username, password):

    SocketHttpConnectionProvider s = new SocketHttpConnectionProvider();
    s.useProxy(ProxyInfo.httpProxy("proxy_url", 1090, null, null));

    HttpResponse response = HttpRequest

HTTP supports HTTP, SOCKS4 and SOCKE5 proxy types.

Parse from InputStreams

Both HttpRequest and HttpResponse have a method readFrom(InputStream). Basically, you can parse input stream with these methods. This is, for example, how you can read request on server side.