49 private final HttpClient httpClient;
50 private final HttpClientConfig config;
58 this.config = config ==
null ? HttpClientConfig.defaults() : config;
59 this.jsonCodec = jsonCodec ==
null ?
JsonUtils.
codec() : jsonCodec;
60 this.httpClient = HttpClient.newBuilder().connectTimeout(this.config.connectTimeout())
61 .followRedirects(this.config.redirectPolicy()).build();
77 public HttpResponseSpec
send(
final HttpRequestSpec request)
throws IOException, InterruptedException {
78 final var response = httpClient.send(buildRequest(request), HttpResponse.BodyHandlers.ofByteArray());
79 return new HttpResponseSpec(response.statusCode(), response.headers().map(), response.body());
83 public <T> T sendJson(
final HttpRequestSpec request,
final TypeReference<T> typeReference)
84 throws IOException, InterruptedException {
85 final var response =
send(request);
86 return jsonCodec.
readValue(response.body(), typeReference);
90 public <T> T sendJson(
final HttpRequestSpec request,
final Class<T> type)
throws IOException, InterruptedException {
91 final var response =
send(request);
92 return jsonCodec.
readValue(response.body(), type);
95 public <T> T sendJson(
final HttpMethod method,
final URI uri,
final Object body,
final Class<T> responseType)
96 throws IOException, InterruptedException {
97 return sendJson(HttpRequestSpec.builder(method, uri).jsonBody(body, jsonCodec).build(), responseType);
100 public <T> T sendJson(
final HttpMethod method,
final URI uri,
final Object body,
101 final TypeReference<T> responseType)
throws IOException, InterruptedException {
102 return sendJson(HttpRequestSpec.builder(method, uri).jsonBody(body, jsonCodec).build(), responseType);
106 throws IOException, InterruptedException {
107 return send(HttpRequestSpec.builder(method, uri).body(body).contentType(
"text/plain; charset=utf-8").build());
110 private HttpRequest buildRequest(
final HttpRequestSpec request) {
111 final var builder = HttpRequest.newBuilder(request.uri())
112 .method(request.method().verb(), requestBodyPublisher(request))
113 .timeout(request.timeout() !=
null ? request.timeout() :
config.requestTimeout());
115 applyHeaders(builder,
config.defaultHeaders());
116 applyHeaders(builder, request.headers());
117 if (
config.userAgent() !=
null && !
config.userAgent().isBlank()) {
118 builder.header(
"User-Agent",
config.userAgent());
120 return builder.build();
123 private static void applyHeaders(
final HttpRequest.Builder builder,
final Map<String, List<String>> headers) {
124 for (
final var entry : headers.entrySet()) {
125 for (
final var value : entry.getValue()) {
126 builder.header(entry.getKey(), value);
131 private static HttpRequest.BodyPublisher requestBodyPublisher(
final HttpRequestSpec request) {
132 final var body = request.body();
133 if (body ==
null || body.length == 0) {
134 return HttpRequest.BodyPublishers.noBody();
136 return HttpRequest.BodyPublishers.ofByteArray(body);