Bael 5481 java httpclient post (#12118)

* BAEL-5481: Create new module

* BAEL-5481: Sync and async example

* BAEL-5481: Concurrent example

* BAEL-5481: Concurrent example

* BAEL-5481: JSON body example

* BAEL-5481: Form data example

* BAEL-5481: File upload example

* BAEL-5481: PR comments + Jenkins

* BAEL-5481: Update aftifact ID

* BAEL-5481: Spaces
This commit is contained in:
Daniel Strmecki
2022-05-11 09:57:02 +02:00
committed by GitHub
parent 9b0893efb8
commit fa64770d60
6 changed files with 387 additions and 0 deletions

View File

@@ -0,0 +1,162 @@
package com.baeldung.httpclient;
import java.io.IOException;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
public class HttpClientPost {
public static HttpResponse<String> sendSynchronousPost(String serviceUrl) throws IOException, InterruptedException {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(serviceUrl))
.POST(HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = client
.send(request, HttpResponse.BodyHandlers.ofString());
return response;
}
public static CompletableFuture<HttpResponse<String>> sendAsynchronousPost(String serviceUrl) {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(serviceUrl))
.POST(HttpRequest.BodyPublishers.noBody())
.build();
CompletableFuture<HttpResponse<String>> futureResponse = client
.sendAsync(request, HttpResponse.BodyHandlers.ofString());
return futureResponse;
}
public static List<CompletableFuture<HttpResponse<String>>> sendConcurrentPost(List<String> serviceUrls) {
HttpClient client = HttpClient.newHttpClient();
List<CompletableFuture<HttpResponse<String>>> completableFutures = serviceUrls.stream()
.map(URI::create)
.map(HttpRequest::newBuilder)
.map(builder -> builder.POST(HttpRequest.BodyPublishers.noBody()))
.map(HttpRequest.Builder::build)
.map(request -> client.sendAsync(request, HttpResponse.BodyHandlers.ofString()))
.collect(Collectors.toList());
return completableFutures;
}
public static HttpResponse<String> sendPostWithAuthHeader(String serviceUrl) throws IOException, InterruptedException {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(serviceUrl))
.POST(HttpRequest.BodyPublishers.noBody())
.header("Authorization", "Basic " + Base64.getEncoder()
.encodeToString(("baeldung:123456").getBytes()))
.build();
HttpResponse<String> response = client
.send(request, HttpResponse.BodyHandlers.ofString());
return response;
}
public static HttpResponse<String> sendPostWithAuthClient(String serviceUrl) throws IOException, InterruptedException {
HttpClient client = HttpClient.newBuilder()
.authenticator(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(
"baeldung",
"123456".toCharArray());
}
})
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(serviceUrl))
.POST(HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = client
.send(request, HttpResponse.BodyHandlers.ofString());
return response;
}
public static HttpResponse<String> sendPostWithJsonBody(String serviceUrl) throws IOException, InterruptedException {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(serviceUrl))
.POST(HttpRequest.BodyPublishers.ofString("{\"action\":\"hello\"}"))
.build();
HttpResponse<String> response = client
.send(request, HttpResponse.BodyHandlers.ofString());
return response;
}
public static HttpResponse<String> sendPostWithFormData(String serviceUrl) throws IOException, InterruptedException {
HttpClient client = HttpClient.newHttpClient();
Map<String, String> formData = new HashMap<>();
formData.put("username", "baeldung");
formData.put("message", "hello");
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(serviceUrl))
.POST(HttpRequest.BodyPublishers.ofString(getFormDataAsString(formData)))
.build();
HttpResponse<String> response = client
.send(request, HttpResponse.BodyHandlers.ofString());
return response;
}
public static HttpResponse<String> sendPostWithFileData(String serviceUrl, Path file) throws IOException, InterruptedException {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(serviceUrl))
.POST(HttpRequest.BodyPublishers.ofFile(file))
.build();
HttpResponse<String> response = client
.send(request, HttpResponse.BodyHandlers.ofString());
return response;
}
private static String getFormDataAsString(Map<String, String> formData) {
StringBuilder formBodyBuilder = new StringBuilder();
for (Map.Entry<String, String> singleEntry : formData.entrySet()) {
if (formBodyBuilder.length() > 0) {
formBodyBuilder.append("&");
}
formBodyBuilder.append(URLEncoder.encode(singleEntry.getKey(), StandardCharsets.UTF_8));
formBodyBuilder.append("=");
formBodyBuilder.append(URLEncoder.encode(singleEntry.getValue(), StandardCharsets.UTF_8));
}
return formBodyBuilder.toString();
}
}

View File

@@ -0,0 +1,99 @@
package com.baeldung.httpclient;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.io.IOException;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import static org.assertj.core.api.Assertions.*;
class HttpClientPostUnitTest extends PostRequestMockServer {
@Test
void givenSyncPostRequest_whenServerIsAvailable_thenOkStatusIsReceived() throws IOException, InterruptedException {
HttpResponse<String> response = HttpClientPost.sendSynchronousPost(serviceUrl);
assertThat(response.statusCode()).isEqualTo(200);
assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}");
}
@Test
void givenAsyncPostRequest_whenServerIsAvailable_thenOkStatusIsReceived() throws ExecutionException, InterruptedException {
CompletableFuture<HttpResponse<String>> futureResponse = HttpClientPost.sendAsynchronousPost(serviceUrl);
HttpResponse<String> response = futureResponse.get();
assertThat(response.statusCode()).isEqualTo(200);
assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}");
}
@Test
void givenConcurrentPostRequests_whenServerIsAvailable_thenOkStatusIsReceived() throws ExecutionException, InterruptedException {
List<CompletableFuture<HttpResponse<String>>> completableFutures = HttpClientPost
.sendConcurrentPost(List.of(serviceUrl, serviceUrl));
CompletableFuture<List<HttpResponse<String>>> combinedFutures = CompletableFuture
.allOf(completableFutures.toArray(new CompletableFuture[0]))
.thenApply(future ->
completableFutures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList()));
List<HttpResponse<String>> responses = combinedFutures.get();
responses.forEach((response) -> {
assertThat(response.statusCode()).isEqualTo(200);
assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}");
});
}
@Test
void givenPostRequestWithAuthClient_whenServerIsAvailable_thenOkStatusIsReceived() throws IOException, InterruptedException {
HttpResponse<String> response = HttpClientPost.sendPostWithAuthClient(serviceUrl);
assertThat(response.statusCode()).isEqualTo(200);
assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}");
}
@Test
void givenPostRequestWithAuthHeader_whenServerIsAvailable_thenOkStatusIsReceived() throws IOException, InterruptedException {
HttpResponse<String> response = HttpClientPost.sendPostWithAuthHeader(serviceUrl);
assertThat(response.statusCode()).isEqualTo(200);
assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}");
}
@Test
void givenPostRequestWithJsonBody_whenServerIsAvailable_thenOkStatusIsReceived() throws IOException, InterruptedException {
HttpResponse<String> response = HttpClientPost.sendPostWithJsonBody(serviceUrl);
assertThat(response.statusCode()).isEqualTo(200);
assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}");
}
@Test
void givenPostRequestWithFormData_whenServerIsAvailable_thenOkStatusIsReceived() throws IOException, InterruptedException {
HttpResponse<String> response = HttpClientPost.sendPostWithFormData(serviceUrl);
assertThat(response.statusCode()).isEqualTo(200);
assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}");
}
@Test
void givenPostRequestWithFileData_whenServerIsAvailable_thenOkStatusIsReceived(@TempDir Path tempDir) throws IOException, InterruptedException {
Path file = tempDir.resolve("temp.txt");
List<String> lines = Arrays.asList("1", "2", "3");
Files.write(file, lines);
HttpResponse<String> response = HttpClientPost.sendPostWithFileData(serviceUrl, file);
assertThat(response.statusCode()).isEqualTo(200);
assertThat(response.body()).isEqualTo("{\"message\":\"ok\"}");
}
}

View File

@@ -0,0 +1,61 @@
package com.baeldung.httpclient;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.mockserver.client.MockServerClient;
import org.mockserver.integration.ClientAndServer;
import org.mockserver.model.HttpStatusCode;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.URISyntaxException;
import static org.mockserver.integration.ClientAndServer.startClientAndServer;
import static org.mockserver.model.HttpRequest.request;
import static org.mockserver.model.HttpResponse.response;
public abstract class PostRequestMockServer {
public static ClientAndServer mockServer;
public static String serviceUrl;
private static int serverPort;
public static final String SERVER_ADDRESS = "127.0.0.1";
public static final String PATH = "/test1";
public static final String METHOD = "POST";
@BeforeAll
static void startServer() throws IOException, URISyntaxException {
serverPort = getFreePort();
serviceUrl = "http://" + SERVER_ADDRESS + ":" + serverPort + PATH;
mockServer = startClientAndServer(serverPort);
mockBasicPostRequest();
}
@AfterAll
static void stopServer() {
mockServer.stop();
}
private static void mockBasicPostRequest() {
new MockServerClient(SERVER_ADDRESS, serverPort)
.when(
request()
.withPath(PATH)
.withMethod(METHOD)
)
.respond(
response()
.withStatusCode(HttpStatusCode.OK_200.code())
.withBody("{\"message\":\"ok\"}")
);
}
private static int getFreePort () throws IOException {
try (ServerSocket serverSocket = new ServerSocket(0)) {
return serverSocket.getLocalPort();
}
}
}