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:
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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\"}");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user