Skip to content

Commit 16fcf45

Browse files
committed
#22 - ENH: Add Map<String,?> option for header() queryParam() and formParam()
1 parent 8aebcde commit 16fcf45

File tree

5 files changed

+137
-14
lines changed

5 files changed

+137
-14
lines changed

client/src/main/java/io/avaje/http/client/DHttpClientRequest.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,16 @@ public HttpClientRequest header(String name, Object value) {
9191
return value != null ? header(name, value.toString()) : this;
9292
}
9393

94+
@Override
95+
public HttpClientRequest header(Map<String, ?> headers) {
96+
if (headers != null) {
97+
for (Map.Entry<String, ?> entry : headers.entrySet()) {
98+
header(entry.getKey(), entry.getValue());
99+
}
100+
}
101+
return this;
102+
}
103+
94104
@Override
95105
public List<String> header(String name) {
96106
final List<String> values = headers.get(name);
@@ -145,7 +155,6 @@ public HttpClientRequest matrixParam(String name, Object value) {
145155
return this;
146156
}
147157

148-
149158
@Override
150159
public HttpClientRequest queryParam(String name, String value) {
151160
url.queryParam(name, value);
@@ -158,6 +167,12 @@ public HttpClientRequest queryParam(String name, Object value) {
158167
return this;
159168
}
160169

170+
@Override
171+
public HttpClientRequest queryParam(Map<String, ?> params) {
172+
url.queryParam(params);
173+
return this;
174+
}
175+
161176
@Override
162177
public HttpClientRequest formParam(String name, String value) {
163178
if (value == null) {
@@ -175,6 +190,16 @@ public HttpClientRequest formParam(String name, Object value) {
175190
return value != null ? formParam(name, value.toString()) : this;
176191
}
177192

193+
@Override
194+
public HttpClientRequest formParam(Map<String, ?> params) {
195+
if (params != null) {
196+
for (Map.Entry<String, ?> entry : params.entrySet()) {
197+
formParam(entry.getKey(), entry.getValue());
198+
}
199+
}
200+
return this;
201+
}
202+
178203
@Override
179204
public HttpClientRequest body(BodyContent bodyContent) {
180205
encodedRequestBody = bodyContent;

client/src/main/java/io/avaje/http/client/HttpClientRequest.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package io.avaje.http.client;
22

3-
import java.io.FileNotFoundException;
43
import java.io.InputStream;
54
import java.net.http.HttpRequest;
65
import java.nio.file.Path;
76
import java.time.Duration;
87
import java.util.List;
8+
import java.util.Map;
99
import java.util.function.Supplier;
1010

1111
/**
@@ -71,6 +71,14 @@ public interface HttpClientRequest {
7171
*/
7272
HttpClientRequest header(String name, Object value);
7373

74+
/**
75+
* Add the headers to the request via map.
76+
*
77+
* @param headers The headers as name value map to add
78+
* @return The request being built
79+
*/
80+
HttpClientRequest header(Map<String, ?> headers);
81+
7482
/**
7583
* Return the header values that have been set for the given header name.
7684
*
@@ -164,14 +172,22 @@ public interface HttpClientRequest {
164172
HttpClientRequest queryParam(String name, String value);
165173

166174
/**
167-
* Add a Integer query parameter
175+
* Add a query parameter
168176
*
169177
* @param name The name of the query parameter
170178
* @param value The value of the query parameter which can be null
171179
* @return The request being built
172180
*/
173181
HttpClientRequest queryParam(String name, Object value);
174182

183+
/**
184+
* Add a multiple query parameters as name value map.
185+
*
186+
* @param params The query parameters
187+
* @return The request being built
188+
*/
189+
HttpClientRequest queryParam(Map<String, ?> params);
190+
175191
/**
176192
* Add a form parameter.
177193
*
@@ -190,6 +206,14 @@ public interface HttpClientRequest {
190206
*/
191207
HttpClientRequest formParam(String name, Object value);
192208

209+
/**
210+
* Add the form parameters via a map.
211+
*
212+
* @param params The form parameters as name value map
213+
* @return The request being built
214+
*/
215+
HttpClientRequest formParam(Map<String, ?> params);
216+
193217
/**
194218
* Set encoded body content.
195219
*/

client/src/main/java/io/avaje/http/client/UrlBuilder.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.net.URLEncoder;
44
import java.nio.charset.StandardCharsets;
5+
import java.util.Map;
56

67
/**
78
* Build a URL typically using a base url and adding path and query parameters.
@@ -89,6 +90,18 @@ public UrlBuilder queryParam(String name, Object value) {
8990
return this;
9091
}
9192

93+
/**
94+
* Append a query parameters.
95+
*/
96+
public UrlBuilder queryParam(Map<String, ?> params) {
97+
if (params != null) {
98+
for (Map.Entry<String, ?> entry : params.entrySet()) {
99+
queryParam(entry.getKey(), entry.getValue());
100+
}
101+
}
102+
return this;
103+
}
104+
92105
/**
93106
* Append a matrix parameter.
94107
* <p>

client/src/test/java/io/avaje/http/client/HelloControllerTest.java

Lines changed: 56 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,7 @@
1111
import java.time.Duration;
1212
import java.time.LocalDate;
1313
import java.time.ZoneId;
14-
import java.util.ArrayList;
15-
import java.util.List;
16-
import java.util.Map;
17-
import java.util.UUID;
14+
import java.util.*;
1815
import java.util.concurrent.CompletableFuture;
1916
import java.util.concurrent.CompletionException;
2017
import java.util.concurrent.ExecutionException;
@@ -31,6 +28,21 @@ class HelloControllerTest extends BaseWebTest {
3128

3229
final HttpClientContext clientContext = client();
3330

31+
@Test
32+
void queryParamMap() {
33+
Map<String, String> params = new LinkedHashMap<>();
34+
params.put("A", "a");
35+
params.put("B", "b");
36+
37+
final HttpResponse<String> hres = clientContext.request()
38+
.path("hello").path("message")
39+
.queryParam(params)
40+
.GET().asString();
41+
42+
assertThat(hres.statusCode()).isEqualTo(200);
43+
assertThat(hres.uri().toString()).isEqualTo("http://localhost:8887/hello/message?A=a&B=b");
44+
}
45+
3446
@Test
3547
void asLines() {
3648
final HttpResponse<Stream<String>> hres =
@@ -246,6 +258,22 @@ void get_notFound() {
246258
assertThat(hres.body()).contains("Not found");
247259
}
248260

261+
@Test
262+
void headers() {
263+
final HttpClientRequest request = clientContext.request();
264+
265+
Map<String, String> headers = new LinkedHashMap<>();
266+
headers.put("A", "a");
267+
headers.put("B", "b");
268+
headers.put("C", "c");
269+
request.header(headers);
270+
request.header("B", "b2");
271+
272+
assertThat(request.header("A")).containsExactly("a");
273+
assertThat(request.header("B")).containsExactly("b", "b2");
274+
assertThat(request.header("C")).containsExactly("c");
275+
}
276+
249277
@Test
250278
void callString() {
251279
final HttpResponse<String> hres = clientContext.request()
@@ -535,7 +563,7 @@ void async_exceptionally_style() {
535563
future.exceptionally(throwable -> {
536564
final HttpException httpException = (HttpException) throwable.getCause();
537565
causeRef.set(httpException);
538-
assertThat(httpException.getStatusCode()).isEqualTo(422);
566+
assertThat(httpException.statusCode()).isEqualTo(422);
539567

540568
return new HelloDto(0, "ErrorResponse", "");
541569

@@ -601,6 +629,23 @@ void postForm() {
601629
assertThat(res.statusCode()).isEqualTo(201);
602630
}
603631

632+
@Test
633+
void postForm_asMap() {
634+
Map<String, String> formParams = new LinkedHashMap<>();
635+
formParams.put("name", "Bazz");
636+
formParams.put("email", "user@foo.com");
637+
formParams.put("url", "http://foo.com");
638+
formParams.put("startDate", LocalDate.of(2030, 12, 03).toString());
639+
640+
final HttpResponse<Void> res = clientContext.request()
641+
.path("hello/saveform")
642+
.formParam(formParams)
643+
.POST()
644+
.asDiscarding();
645+
646+
assertThat(res.statusCode()).isEqualTo(201);
647+
}
648+
604649
@Test
605650
void postForm_returningBean() {
606651

@@ -662,7 +707,7 @@ void postForm_asVoid_invokesValidation_expect_badRequest_extractError() {
662707
fail();
663708

664709
} catch (HttpException e) {
665-
assertEquals(422, e.getStatusCode());
710+
assertEquals(422, e.statusCode());
666711

667712
final HttpResponse<?> httpResponse = e.getHttpResponse();
668713
assertNotNull(httpResponse);
@@ -693,7 +738,7 @@ void asyncAsVoid_extractError() throws InterruptedException {
693738
final HttpException cause = (HttpException) throwable.getCause();
694739
ref.set(cause);
695740

696-
final HttpResponse<?> httpResponse = cause.getHttpResponse();
741+
final HttpResponse<?> httpResponse = cause.httpResponse();
697742
assertNotNull(httpResponse);
698743
assertEquals(422, httpResponse.statusCode());
699744

@@ -728,7 +773,7 @@ void callAsVoid_async_extractError() throws InterruptedException {
728773
final HttpException cause = (HttpException) throwable.getCause();
729774
ref.set(cause);
730775

731-
final HttpResponse<?> httpResponse = cause.getHttpResponse();
776+
final HttpResponse<?> httpResponse = cause.httpResponse();
732777
assertNotNull(httpResponse);
733778
assertEquals(422, httpResponse.statusCode());
734779

@@ -759,7 +804,7 @@ void callAsVoid_extractError() {
759804

760805
fail();
761806
} catch (HttpException e) {
762-
final HttpResponse<?> httpResponse = e.getHttpResponse();
807+
final HttpResponse<?> httpResponse = e.httpResponse();
763808
assertNotNull(httpResponse);
764809
assertEquals(422, httpResponse.statusCode());
765810

@@ -782,9 +827,9 @@ void postForm_asBytes_validation_expect_badRequest_extractError() {
782827
fail();
783828

784829
} catch (HttpException e) {
785-
assertEquals(422, e.getStatusCode());
830+
assertEquals(422, e.statusCode());
786831

787-
final HttpResponse<?> httpResponse = e.getHttpResponse();
832+
final HttpResponse<?> httpResponse = e.httpResponse();
788833
assertNotNull(httpResponse);
789834
assertEquals(422, httpResponse.statusCode());
790835

client/src/test/java/io/avaje/http/client/UrlBuilderTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import java.time.LocalDate;
88
import java.time.LocalDateTime;
99
import java.time.LocalTime;
10+
import java.util.LinkedHashMap;
11+
import java.util.Map;
1012
import java.util.UUID;
1113

1214
import static org.assertj.core.api.Assertions.assertThat;
@@ -111,6 +113,20 @@ void queryParam_when_many() {
111113
assertThat(url).isEqualTo("https://foo?a=a&b=true&c=false&d=1&e=2&f=13:42&g=2020-01-04&h=2020-01-04T13:44");
112114
}
113115

116+
@Test
117+
void queryParam_when_map() {
118+
Map<String,String> params = new LinkedHashMap<>();
119+
params.put("A", "a");
120+
params.put("B", "b");
121+
params.put("C", "c");
122+
123+
final UrlBuilder urlBuilder = foo()
124+
.queryParam(params)
125+
.queryParam("B", "b2");
126+
127+
assertThat(urlBuilder.build()).isEqualTo("https://foo?A=a&B=b&C=c&B=b2");
128+
}
129+
114130
@Test
115131
void queryParam_when_uuid() {
116132
UUID uuid = UUID.randomUUID();

0 commit comments

Comments
 (0)