- Notifications
You must be signed in to change notification settings - Fork119
timboudreau/netty-http-client
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
This project is fairly obsolete - there is a good HTTP client in the JDK now. Use it. Thisproject will be maintained for a while yet, due to use of the adjacent HTTP test-harness that uses thislibrary 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 byNode.jshttp module; it is designed to (mostly) avoid theFuture pattern, and do its business via callbacks. Wherever possible we avoidintroducing complicated abstractions that try to hide the business of HTTPcommunication; rather your code can be involved in as much or as littleof that as necessary.
You can use it from Maven projectsas described here.
- 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 thejavadoc. The header writing/parsing classes come fromacteur-util; some URL-related classes aredocumented here.
To use with Maven, add the Maven repo to your project asdescribed here. Then add groupIdcom.mastfrog artifactIdnetty-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.
The first thing you need is anHttpClient:
HttpClientclient =HttpClient.builder().followRedirects().build();
The API is callback-based. While you can block the current thread until a response is received usingResponseFuture.await(),the entirepoint 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 listenforState objects which exist for every state transition in the processof making a request and handling the response; or you can provide a simpler callback whichwill be called with the response once it arrives. This looks like
ResponseFutureh =client.get().setURL ("http://localhost:9333/foo/bar" )).execute (newResponseHandler <String> (String.class ) {protectedvoidreceive (HttpResponseStatusstatus,HttpHeadersheaders,Stringresponse ) {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 theResponseHandler callback is parameterized on String - you can get your content as astring, byte array, InputStream or Netty ByteBuf. You can also pass other types; Jackson is used todeserialize JSON, and is the default for unknown types (this may fail if Jackson does not know how toserialize it).
You can get all the detailsby providing aReceiver<State<?>> when you build a request; there are states forthings like Connecting, HeadersReceived; you can even capture every chunk of chunkedencoding individually if you want.
ResponseFuturef =client.get() .setURL("http://localhost:9333/foo/bar" ) .setBody("This is a test",MediaType.PLAIN_TEXT_UTF_8) .onEvent(newReceiver<State<?>>() {publicvoidreceive(State<?>state ) {System.out.println("STATE " +state +" " +state.name() +" " +state.get() );if (state.stateType() ==StateType.Finished ) {DefaultFullHttpResponsed = (DefaultFullHttpResponse)state.get();//do something } } }).execute();
This is a young library; it works, but it will surely need some polish yet; and Netty 4.x is stillchanging, 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-SinceandIf-None-Matchheaders - Zero copy file streaming using Netty's FileRegion
- Better tests (actually start a local server, etc)
MIT license - do what thou wilt, give credit where it's due
Alongside this project is thenetty-http-test-harness project. It providesa fluent interface for writing tests of an HTTP server. The server can be anything -theServer interface has no particular dependencies (but is implemented inActeur if you're using that) - it just hasstart/stop methods and a port property.
The point is to make it very little code or setup to test something.
Basically you construct aTestHarness instance - passing it aServer, aURL for the base URL and aShutdownHookRegistry (another simple interface,fromGiulius. Or to do it the easy way,and useTestHarness.Module andGiulius-Testsas inthis example.
Here's an example:
DateTimehelloLastModified =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);DateTimeaLastModified =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);
About
An asynchronous http client in Java, with a clean, callback-based API, using Netty 4.x
Topics
Resources
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors3
Uh oh!
There was an error while loading.Please reload this page.