• Stars
    star
    319
  • Rank 131,491 (Top 3 %)
  • Language
    Java
  • Created over 11 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An asynchronous http client in Java, with a clean, callback-based API, using Netty 4.x

Netty HTTP Client

This project is fairly obsolete - there is a good HTTP client in the JDK now. Use it. This project will be maintained for a while yet, due to use of the adjacent HTTP test-harness that uses this library under the hood.


An asynchronous http client in Java, with a clean, callback-based API, using Netty 4.x.

The API is inspired a bit by Node.js http module; it is designed to (mostly) avoid the Future pattern, and do its business via callbacks. Wherever possible we avoid introducing complicated abstractions that try to hide the business of HTTP communication; rather your code can be involved in as much or as little of that as necessary.

You can use it from Maven projects as described here.

Features

  • HTTP and HTTPS
  • Simple support for Basic authentication
  • Optional support for HTTP cookies
  • Easy, typed API for setting headers
  • Fluent builder API for assembling requests
  • Non-blocking, asynchronous
  • Small, low-surface-area API
  • Pluggable support for SSLContext/TrustManagers for HTTPS

Read the javadoc. The header writing/parsing classes come from acteur-util; some URL-related classes are documented here.

To use with Maven, add the Maven repo to your project as described here. Then add groupId com.mastfrog artifactId netty-http-client to your POM file.

This project also comes with a test harness which is easy to integrate with unit tests, with built-in methods to assert that the response is what you expect, e.g.

        harness.get("static/hello.txt").setTimeout(Duration.seconds(1)).go()
                .assertHasContent()
                .assertStatus(OK)
                .assertHasHeader(Headers.LAST_MODIFIED.name())
                .assertHasHeader(Headers.ETAG.name())
                .assertContent("hello world")
                .getHeader(Headers.LAST_MODIFIED);

See the bottom of this document for test harness documentation.

Usage

The first thing you need is an HttpClient:

	HttpClient client = HttpClient.builder().followRedirects().build();

The API is callback-based. While you can block the current thread until a response is received using ResponseFuture.await(), the entire point of an async I/O is defeated if you do that. Asynchronous programming means learning to love callbacks.

There are two ways to pay attention to the results of an HTTP call - you can listen for State objects which exist for every state transition in the process of making a request and handling the response; or you can provide a simpler callback which will be called with the response once it arrives. This looks like

	ResponseFuture h = client
		.get().setURL ( "http://localhost:9333/foo/bar" ))
		.execute ( new ResponseHandler <String> ( String.class ) {

            protected void receive ( HttpResponseStatus status, HttpHeaders headers, String response ) {
                System.out.println ( "Here's the response: '" + response + "'" );
            }
        });

(ResponseHandler has additional methods you can override to detect error responses, timeouts or refused connections)

You'll note the ResponseHandler callback is parameterized on String - you can get your content as a string, byte array, InputStream or Netty ByteBuf. You can also pass other types; Jackson is used to deserialize JSON, and is the default for unknown types (this may fail if Jackson does not know how to serialize it).

The Details

You can get all the details by providing a Receiver<State<?>> when you build a request; there are states for things like Connecting, HeadersReceived; you can even capture every chunk of chunked encoding individually if you want.

        ResponseFuture f = client.get()
                .setURL( "http://localhost:9333/foo/bar" )
                .setBody( "This is a test", MediaType.PLAIN_TEXT_UTF_8)
                .onEvent( new Receiver<State<?>>() {

            public void receive( State<?> state ) {
                System.out.println( "STATE " + state + " " + state.name() + " " + state.get() );
                if ( state.stateType() == StateType.Finished ) {
                    DefaultFullHttpResponse d = (DefaultFullHttpResponse) state.get();
		    //do something
                }
            }

        }).execute();

Status & To-Dos

This is a young library; it works, but it will surely need some polish yet; and Netty 4.x is still changing, including occasional incompatible changes. Here are some things that would be useful to add:

  • Caching on disk or in memory with proper use of If-Modified-Since and If-None-Match headers
  • Zero copy file streaming using Netty's FileRegion
  • Better tests (actually start a local server, etc)

License

MIT license - do what thou wilt, give credit where it's due

Test Harness (netty-http-test-harness)

Alongside this project is the netty-http-test-harness project. It provides a fluent interface for writing tests of an HTTP server. The server can be anything - the Server interface has no particular dependencies (but is implemented in Acteur if you're using that) - it just has start/stop methods and a port property.

The point is to make it very little code or setup to test something.

Basically you construct a TestHarness instance - passing it a Server, a URL for the base URL and a ShutdownHookRegistry (another simple interface, from Giulius. Or to do it the easy way, and use TestHarness.Module and Giulius-Tests as in this example.

Here's an example:

        DateTime helloLastModified = har.get("static/hello.txt").go()
                .assertHasContent()
                .assertStatus(OK)
                .assertHasHeader(Headers.LAST_MODIFIED.name())
                .assertHasHeader(Headers.ETAG.name())
                .assertContent(HELLO_CONTENT)
                .getHeader(Headers.LAST_MODIFIED);

        DateTime aLastModified = har.get("static/another.txt").go()
                .assertStatus(OK)
                .assertHasContent()
                .assertHasHeader(Headers.LAST_MODIFIED.name())
                .assertHasHeader(Headers.ETAG.name())
                .assertContent("This is another file.  It has some data in it.\n")
                .getHeader(Headers.LAST_MODIFIED);

        assertNotNull(helloLastModified);
        assertNotNull(aLastModified);

        har.get("static/hello.txt")
                .addHeader(Headers.IF_MODIFIED_SINCE, helloLastModified)
                .go()
                .assertStatus(NOT_MODIFIED);

        har.get("static/another.txt")
                .addHeader(Headers.IF_MODIFIED_SINCE, aLastModified)
                .go().assertStatus(NOT_MODIFIED);

More Repositories

1

nb-nodejs

NodeJS support for NetBeans, originally hosted on netbeans.org
Java
91
star
2

acteur

A framework for writing lightweight, scalable servers with Guice and Netty
Java
67
star
3

tiny-maven-proxy

A tiny maven proxy
Java
65
star
4

vl-jung

NetBeans Visual Library integration with JUNG (Java Universal Graph Library) for rich, animated visualizations of graphs using real components
Java
27
star
5

scamper

A toolkit for creating SCTP servers and clients
Java
22
star
6

giulius

Tools for loading file-based configuration files and mapping them with Guice's ``@Named`` and more
Java
18
star
7

scamper-chat

An IRC-like chat client and server using SCTP, based on Scamper+Netty
Java
14
star
8

netbeans-mongodb

A NetBeans plugin for browsing MongoDB
Java
13
star
9

giulius-selenium-tests

A test harness that allows Selenium tests to be run using JUnit and test fixtures to be created and injected by a WebDriver-aware Guice
Java
12
star
10

scopes

A framework for writing custom Guice scopes
Java
11
star
11

meta-update-center

An update server for NetBeans Plugins which serves remotely built NBM files
Java
10
star
12

avatar

A container project for building AvatarJS
JavaScript
10
star
13

gittattle

A simple, minimal web ui for git using node.js
JavaScript
8
star
14

adhoc-projects

NetBeans Plugin to make any folder a project
Java
8
star
15

acteur-tutorial

A tutorial for the acteur lightweight Netty+Guice server framework
Java
7
star
16

bunyan-java

A little logging library that uses the format of NodeJS's bunyan JSON logger
Java
7
star
17

util

Misc Java utilities - strings, streams, threading, collections
Java
7
star
18

generic-web-api

A library for quickly creating REST API clients
Java
6
star
19

imagine

Java
5
star
20

netbeans-contrib

Fork of netbeans contrib repo
Java
5
star
21

blather

Async Java websocket client and test harness
Java
4
star
22

gentoo

A gentoo portage overlay with etcd, statsd and some fonts
Shell
4
star
23

netbeans-local-maven-repo-populator

Populate your local Maven repository with modules from a Netbeans source build
Shell
4
star
24

mongo-promises

Promise-based wrappers for MongoDB's async Java API
Java
4
star
25

jhtm

Implements some ideas from NuPIC in Java
Java
3
star
26

giulius-settings-etcd

Load application configuration from a cluster of etcd instances
Java
3
star
27

giulius-tests

A JUnit test runner for Guice that lets test methods take arguments
Java
3
star
28

acteur-wicket

Run apache wicket applications without a servlet container, in Netty + Acteur
Java
3
star
29

annotation-tools

Toolkit for making writing complex Java annotation processors easy
Java
3
star
30

simplevalidation

The SimpleValidation project, used in NetBeans and originally hosted on kenai.com
Java
3
star
31

numble

Generates typesafe, JSON-friendly Java classes with validation, from a description of input data as names and types
Java
3
star
32

portable-crypto

NodeJS and Java libraries for strong symmetric encryption which can interoperate with each other and have few or no dependencies
Java
2
star
33

mastfrog-parent

Master build for a bunch of related projects which are linked in as git submodules
Java
2
star
34

netbeans-povray-syntax

NetBeans editor support for POV-Ray syntax
Java
2
star
35

vmstat-statsd-agent

Parses output from vmstat and feeds it to a statsd / graphite instance
JavaScript
2
star
36

bunyan-java-v2

Output-compatible port of NodeJS's bunyan JSON logging framework to Java
Java
2
star
37

blurt

A little thing for fire-and-forget UDP packets with Java and NodeJS implementations
Java
2
star
38

desktop

Geometry, color palette and desktop component utilities
Java
2
star
39

netty-dns-support

Enhances Netty's DNS support with the ability to parse and programmatically manipulate DNS records with a clean API
Java
1
star
40

concordance-to-xls-tool

Attempts to convert LexisNexis "load file" documents created by Concordance into something usable by mere mortals (XLS, CSV or JSON)
Java
1
star
41

simpleproxy

A really, really simple HTTP proxy for debugging things
JavaScript
1
star
42

atomic-state

Java annotation to implement an interface over an `int` or `long` and generate atomic and listener support
Java
1
star
43

storage

Libraries for building high-performance, single-purpose micro-databases with indexes over memory-mapped files in Java
Java
1
star
44

pectin

A little library for writing lambda-ized HTTP servers
Java
1
star
45

visual-library-tabcontrol

A replacement editor tab ui delegate for NetBeans with lots of bling complements of Visual Library
Java
1
star
46

colorchooser

A swing color chooser, formerly hosted on java.net
Java
1
star