Skip to content

Commit 780e63d

Browse files
committed
Update README
1 parent ce15136 commit 780e63d

File tree

1 file changed

+150
-26
lines changed

1 file changed

+150
-26
lines changed

README.md

Lines changed: 150 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ A light weight wrapper to the JDK 11+ Java Http Client
44

55
- Adds a fluid API for request constructing URL and payload
66
- Adds JSON marshalling/unmarshalling of request and response using Jackson or Gson
7-
- Adds request/response logging
7+
- Gzip encoding/decoding
8+
- Logging of request/response logging
9+
- Interception of request/response
10+
- Built in support for authorization via Basic Auth and Bearer Token
11+
812

913

1014

@@ -35,44 +39,130 @@ Create a HttpClientContext with a baseUrl, Jackson or Gson based JSON
3539

3640
```
3741

38-
### Requests
42+
## Requests
3943

4044
From HttpClientContext:
4145
- Create a request
4246
- Build the url via path(), matrixParam(), queryParam()
4347
- Optionally set headers(), cookies() etc
44-
- Optionally specify a request body (JSON, form, or raw BodyPublisher)
48+
- Optionally specify a request body (JSON, form, or any JDK BodyPublisher)
4549
- Http verbs - GET(), POST(), PUT(), PATCH(), DELETE(), HEAD(), TRACE()
46-
- Optionally return response body as a bean, list of beans, stream of beans or various raw response types
47-
- Optionally use Async processing of the request
50+
51+
- Sync processing response body as:
52+
- a bean, list of beans, stream of beans, String, Void or any JDK Response.BodyHandler
53+
54+
- Async processing of the request using CompleteableFuture
55+
- a bean, list of beans, stream of beans, String, Void or any JDK Response.BodyHandler
56+
57+
58+
59+
## Limitations:
60+
- NO support for POSTing multipart-form currently
61+
62+
63+
#### Example GET as String
64+
```java
65+
HttpResponse<String> hres = clientContext.request()
66+
.path("hello")
67+
.GET()
68+
.asString();
69+
```
70+
71+
72+
## Overview of responses
73+
74+
Overview of response types for sync calls.
75+
76+
<table style="width:100%;">
77+
<tr><td><b>sync processing</b></td><td>&nbsp;</td></tr>
78+
<tr><td>asVoid</td><td>HttpResponse&lt;Void&gt;</td></tr>
79+
<tr><td>asString</td><td>HttpResponse&lt;String&gt;</td></tr>
80+
<tr><td>bean&lt;E&gt</td><td>E</td></tr>
81+
<tr><td>list&lt;E&gt</td><td>List&lt;E&gt;</td></tr>
82+
<tr><td>stream&lt;E&gt</td><td>Stream&lt;E&gt;</td></tr>
83+
<tr><td>withHandler(HttpResponse.BodyHandler&lt;E&gt;)</td><td>E</td></tr>
84+
<tr><td>&nbsp;</td><td>&nbsp;</td></tr>
85+
<tr><td><b>async processing</b></td><td>&nbsp;</td></tr>
86+
<tr><td>asVoid</td><td>CompleteableFuture&lt;Void&gt;</td></tr>
87+
<tr><td>asString</td><td>CompleteableFuture&lt;String&gt;</td></tr>
88+
<tr><td>bean&lt;E&gt</td><td>CompleteableFuture&lt;E&gt;</td></tr>
89+
<tr><td>list&lt;E&gt</td><td>CompleteableFuture&lt;List&lt;E&gt;&gt;</td></tr>
90+
<tr><td>stream&lt;E&gt</td><td>CompleteableFuture&lt;Stream&lt;E&gt;&gt;</td></tr>
91+
<tr><td>withHandler(HttpResponse.BodyHandler&lt;E&gt)</td><td>CompleteableFuture&lt;E&gt;</td></tr>
92+
</table>
93+
94+
### JDK BodyHandlers
95+
96+
JDK HttpClient provides a number of BodyHandlers including reactive Flow based subscribers.
97+
With the `withHandler()` methods we can use any of these or our own `HttpResponse.BodyHandler`
98+
implementation.
99+
100+
Reference https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpResponse.BodyHandlers.html
101+
102+
<table style="width:100%;">
103+
<tr><td>discarding()</td><td>Discards the response body</td></tr>
104+
<tr><td>ofByteArray()</td><td>byte[]</td></tr>
105+
<tr><td>ofString()</td><td>String, additional charset option</td></tr>
106+
<tr><td>ofLines()</td><td>Stream&lt;String&gt;</td></tr>
107+
<tr><td>ofInputStream()</td><td>InputStream</td></tr>
108+
109+
<tr><td>ofFile(Path file)</td><td>Path with various options</td></tr>
110+
<tr><td>ofByteArrayConsumer(...)</td><td>&nbsp;</td></tr>
111+
<tr><td>fromSubscriber</td><td>various options</td></tr>
112+
<tr><td>fromLineSubscriber</td><td>various options</td></tr>
113+
</table>
48114

49115
## Examples
50116

51-
GET as String
117+
#### GET as String
52118
```java
53119
HttpResponse<String> hres = clientContext.request()
54120
.path("hello")
55121
.GET()
56122
.asString();
57123
```
58124

59-
GET as json to single bean
125+
#### Async GET as String
126+
- All async requests use JDK httpClient.sendAsync(...) returning CompleteableFuture&lt;T&gt;
127+
- throwable is a CompletionException
128+
- In the example below hres is of type HttpResponse&lt;String&gt;
129+
130+
```java
131+
clientContext.request()
132+
.path("hello")
133+
.GET()
134+
.async().asString()
135+
.whenComplete((hres, throwable) -> {
136+
137+
if (throwable != null) {
138+
// CompletionException
139+
...
140+
} else {
141+
// HttpResponse&lt;String&gt;
142+
int statusCode = hres.statusCode();
143+
String body = hres.body();
144+
...
145+
}
146+
});
147+
```
148+
149+
#### GET as json to single bean
60150
```java
61151
Customer customer = clientContext.request()
62152
.path("customers").path(42)
63153
.GET()
64154
.bean(Customer.class);
65155
```
66156

67-
GET as json to a list of beans
157+
#### GET as json to a list of beans
68158
```java
69159
List<Customer> list = clientContext.request()
70160
.path("customers")
71161
.GET()
72162
.list(Customer.class);
73163
```
74164

75-
GET as `application/x-json-stream` as a stream of beans
165+
#### GET as `application/x-json-stream` as a stream of beans
76166
```java
77167
Stream<Customer> stream = clientContext.request()
78168
.path("customers/all")
@@ -81,12 +171,12 @@ Stream<Customer> stream = clientContext.request()
81171
```
82172

83173

84-
POST a bean as json request body
174+
#### POST a bean as json request body
85175
```java
86-
HelloDto bean = new HelloDto(12, "rob", "other");
176+
Hello bean = new Hello(42, "rob", "other");
87177

88178
HttpResponse<Void> res = clientContext.request()
89-
.path("hello/savebean")
179+
.path("hello")
90180
.body(bean)
91181
.POST()
92182
.asDiscarding();
@@ -95,7 +185,11 @@ assertThat(res.statusCode()).isEqualTo(201);
95185
```
96186

97187

98-
Path
188+
#### Path
189+
190+
Multiple calls to `path()` append with a `/`. This is make it easier to build a path
191+
programmatically and also build paths that include `matrixParam()`
192+
99193
```java
100194
HttpResponse<String> res = clientContext.request()
101195
.path("customers")
@@ -112,27 +206,29 @@ HttpResponse<String> res = clientContext.request()
112206
.asString();
113207
```
114208

115-
MatrixParam
209+
#### MatrixParam
116210
```java
117211
HttpResponse<String> httpRes = clientContext.request()
118212
.path("books")
119213
.matrixParam("author", "rob")
120214
.matrixParam("country", "nz")
121215
.path("foo")
122216
.matrixParam("extra", "banana")
123-
.GET().asString();
217+
.GET()
218+
.asString();
124219
```
125220

126-
QueryParam
221+
#### QueryParam
127222
```java
128223
List<Product> beans = clientContext.request()
129224
.path("products")
130225
.queryParam("sortBy", "name")
131226
.queryParam("maxCount", "100")
132-
.GET().list(Product.class);
227+
.GET()
228+
.list(Product.class);
133229
```
134230

135-
FormParam
231+
#### FormParam
136232
```java
137233
HttpResponse<Void> res = clientContext.request()
138234
.path("register/user")
@@ -146,10 +242,21 @@ HttpResponse<Void> res = clientContext.request()
146242
assertThat(res.statusCode()).isEqualTo(201);
147243
```
148244

149-
## Currently, NO support for POSTing multipart-form
245+
150246

151247
## Async processing
152248

249+
All async requests use JDK httpClient.sendAsync(...) returning CompleteableFuture&lt;T&gt;
250+
251+
<table style="width:100%;">
252+
<tr><td>asVoid</td><td>CompleteableFuture&lt;Void&gt;</td></tr>
253+
<tr><td>asString</td><td>CompleteableFuture&lt;String&gt;</td></tr>
254+
<tr><td>bean&lt;E&gt</td><td>CompleteableFuture&lt;E&gt;</td></tr>
255+
<tr><td>list&lt;E&gt</td><td>CompleteableFuture&lt;List&lt;E&gt;&gt;</td></tr>
256+
<tr><td>stream&lt;E&gt</td><td>CompleteableFuture&lt;Stream&lt;E&gt;&gt;</td></tr>
257+
<tr><td>withHandler(HttpResponse.BodyHandler&lt;E&gt)</td><td>CompleteableFuture&lt;E&gt</td></tr>
258+
</table>
259+
153260
### .async().asDiscarding() - HttpResponse&lt;Void&gt;
154261

155262
```java
@@ -214,7 +321,7 @@ clientContext.request()
214321

215322
```
216323

217-
### .async().withHandler(...) - Any response body handler
324+
### .async().withHandler(...) - Any `Response.BodyHandler` implementation
218325

219326
The example below is a line subscriber processing response content line by line.
220327

@@ -230,6 +337,7 @@ CompletableFuture<HttpResponse<Void>> future = clientContext.request()
230337
}
231338
@Override
232339
public void onNext(String item) {
340+
// process the line of response content
233341
...
234342
}
235343
@Override
@@ -248,10 +356,27 @@ CompletableFuture<HttpResponse<Void>> future = clientContext.request()
248356

249357
```
250358

359+
## BasicAuthIntercept - Authorization Basic / Basic Auth
360+
361+
We can use `BasicAuthIntercept` to intercept all requests adding a `Authorization: Basic ...`
362+
header ("Basic Auth").
363+
364+
##### Example
365+
366+
```java
367+
HttpClientContext clientContext =
368+
HttpClientContext.newBuilder()
369+
.withBaseUrl(baseUrl)
370+
...
371+
.withRequestIntercept(new BasicAuthIntercept("myUsername", "myPassword")) <!-- HERE
372+
.build();
373+
```
374+
251375

252-
## Auth token
376+
## AuthTokenProvider - Authorization Bearer token
253377

254-
Built in support for obtaining and setting an Authorization token.
378+
For Authorization using `Bearer` tokens that are obtained and expire, implement `AuthTokenProvider`
379+
and register that when building the HttpClientContext.
255380

256381
### 1. Implement AuthTokenProvider
257382

@@ -280,14 +405,13 @@ Built in support for obtaining and setting an Authorization token.
280405
```java
281406
HttpClientContext ctx = HttpClientContext.newBuilder()
282407
.withBaseUrl("https://foo")
283-
.withBodyAdapter(new JacksonBodyAdapter(objectMapper))
284-
.withRequestListener(new RequestLogger())
408+
...
285409
.withAuthTokenProvider(new MyAuthTokenProvider()) <!-- HERE
286410
.build();
287411
```
288412

289413
### 3. Token obtained and set automatically
290414

291-
Now all requests using the HttpClientContext will automatically get
415+
All requests using the HttpClientContext will automatically get
292416
an `Authorization` header with `Bearer` token added. The token will be
293-
obtained when necessary.
417+
obtained for initial request and then renewed when the token has expired.

0 commit comments

Comments
 (0)