[JAVA-15024] Upgraded multipart functionality to apache client 5 (#13378)

Co-authored-by: panagiotiskakos <panagiotis.kakos@libra-is.com>
This commit is contained in:
panos-kakos 2023-02-02 17:04:40 +00:00 committed by GitHub
parent 695546987f
commit 7fa5e1159b
3 changed files with 152 additions and 106 deletions

View File

@ -54,6 +54,42 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.core5</groupId>
<artifactId>httpcore5</artifactId>
<version>${httpcore5.version}</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5-fluent</artifactId>
<version>${httpclient5-fluent.version}</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>${httpclient5.version}</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock</artifactId>
@ -78,6 +114,10 @@
<!-- testing -->
<wiremock.version>2.5.1</wiremock.version>
<httpclient.version>4.5.8</httpclient.version> <!-- 4.3.6 --> <!-- 4.4-beta1 -->
<!-- http client & core 5 -->
<httpcore5.version>5.2</httpcore5.version>
<httpclient5.version>5.2</httpclient5.version>
<httpclient5-fluent.version>5.2</httpclient5-fluent.version>
</properties>
</project>

View File

@ -1,19 +1,24 @@
package com.baeldung.httpclient;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.entity.mime.FileBody;
import org.apache.hc.client5.http.entity.mime.HttpMultipartMode;
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
import org.apache.hc.client5.http.entity.mime.StringBody;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.HttpStatus;
import java.io.BufferedReader;
import java.io.File;
@ -22,14 +27,10 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import com.baeldung.httpclient.handler.CustomHttpClientResponseHandler;
public class HttpClientMultipartLiveTest {
class HttpClientMultipartLiveTest {
// No longer available
// private static final String SERVER = "http://echo.200please.com";
@ -38,41 +39,16 @@ public class HttpClientMultipartLiveTest {
private static final String TEXTFILENAME = "temp.txt";
private static final String IMAGEFILENAME = "image.jpg";
private static final String ZIPFILENAME = "zipFile.zip";
private static final Logger LOGGER = Logger.getLogger("com.baeldung.httpclient.HttpClientMultipartLiveTest");
private CloseableHttpClient client;
private HttpPost post;
private BufferedReader rd;
private CloseableHttpResponse response;
@Before
public final void before() {
client = HttpClientBuilder.create()
.build();
@BeforeEach
public void before() {
post = new HttpPost(SERVER);
}
@After
public final void after() throws IllegalStateException, IOException {
post.completed();
try {
client.close();
} catch (final IOException e1) {
LOGGER.log(Level.SEVERE, e1.getMessage(), e1);
throw e1;
}
try {
rd.close();
} catch (final IOException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
throw e;
}
ResponseUtil.closeResponse(response);
}
// tests
@Test
public final void givenFileandMultipleTextParts_whenUploadwithAddPart_thenNoExceptions() throws IOException {
void givenFileandMultipleTextParts_whenUploadwithAddPart_thenNoExceptions() throws IOException {
final URL url = Thread.currentThread()
.getContextClassLoader()
.getResource("uploads/" + TEXTFILENAME);
@ -83,53 +59,61 @@ public class HttpClientMultipartLiveTest {
final StringBody stringBody2 = new StringBody("This is message 2", ContentType.MULTIPART_FORM_DATA);
//
final MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.setMode(HttpMultipartMode.LEGACY);
builder.addPart("file", fileBody);
builder.addPart("text1", stringBody1);
builder.addPart("text2", stringBody2);
final HttpEntity entity = builder.build();
//
post.setEntity(entity);
response = client.execute(post);
final int statusCode = response.getStatusLine()
.getStatusCode();
final String responseString = getContent();
final String contentTypeInHeader = getContentTypeHeader();
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
// assertTrue(responseString.contains("Content-Type: multipart/form-data;"));
assertTrue(contentTypeInHeader.contains("Content-Type: multipart/form-data;"));
System.out.println(responseString);
System.out.println("POST Content Type: " + contentTypeInHeader);
post.setEntity(entity);
try(CloseableHttpClient client = HttpClientBuilder.create()
.build();
CloseableHttpResponse response = (CloseableHttpResponse) client
.execute(post, new CustomHttpClientResponseHandler())){
final int statusCode = response.getCode();
final String responseString = getContent(response.getEntity());
final String contentTypeInHeader = getContentTypeHeader();
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
assertTrue(contentTypeInHeader.contains("Content-Type: multipart/form-data;"));
System.out.println(responseString);
System.out.println("POST Content Type: " + contentTypeInHeader);
}
}
@Test
public final void givenFileandTextPart_whenUploadwithAddBinaryBodyandAddTextBody_ThenNoExeption() throws IOException {
void givenFileandTextPart_whenUploadwithAddBinaryBodyandAddTextBody_ThenNoExeption() throws IOException {
final URL url = Thread.currentThread()
.getContextClassLoader()
.getResource("uploads/" + TEXTFILENAME);
final File file = new File(url.getPath());
final String message = "This is a multipart post";
final MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.setMode(HttpMultipartMode.LEGACY);
builder.addBinaryBody("file", file, ContentType.DEFAULT_BINARY, TEXTFILENAME);
builder.addTextBody("text", message, ContentType.DEFAULT_BINARY);
final HttpEntity entity = builder.build();
post.setEntity(entity);
response = client.execute(post);
final int statusCode = response.getStatusLine()
.getStatusCode();
final String responseString = getContent();
final String contentTypeInHeader = getContentTypeHeader();
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
// assertTrue(responseString.contains("Content-Type: multipart/form-data;"));
assertTrue(contentTypeInHeader.contains("Content-Type: multipart/form-data;"));
System.out.println(responseString);
System.out.println("POST Content Type: " + contentTypeInHeader);
try(CloseableHttpClient client = HttpClientBuilder.create()
.build();
CloseableHttpResponse response = (CloseableHttpResponse) client
.execute(post, new CustomHttpClientResponseHandler())){
final int statusCode = response.getCode();
final String responseString = getContent(response.getEntity());
final String contentTypeInHeader = getContentTypeHeader();
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
assertTrue(contentTypeInHeader.contains("Content-Type: multipart/form-data;"));
System.out.println(responseString);
System.out.println("POST Content Type: " + contentTypeInHeader);
}
}
@Test
public final void givenFileAndInputStreamandText_whenUploadwithAddBinaryBodyandAddTextBody_ThenNoException() throws IOException {
void givenFileAndInputStreamandText_whenUploadwithAddBinaryBodyandAddTextBody_ThenNoException() throws IOException {
final URL url = Thread.currentThread()
.getContextClassLoader()
.getResource("uploads/" + ZIPFILENAME);
@ -140,64 +124,75 @@ public class HttpClientMultipartLiveTest {
final File file = new File(url2.getPath());
final String message = "This is a multipart post";
final MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.setMode(HttpMultipartMode.STRICT);
builder.addBinaryBody("file", file, ContentType.DEFAULT_BINARY, IMAGEFILENAME);
builder.addBinaryBody("upstream", inputStream, ContentType.create("application/zip"), ZIPFILENAME);
builder.addTextBody("text", message, ContentType.TEXT_PLAIN);
final HttpEntity entity = builder.build();
post.setEntity(entity);
response = client.execute(post);
final int statusCode = response.getStatusLine()
.getStatusCode();
final String responseString = getContent();
final String contentTypeInHeader = getContentTypeHeader();
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
// assertTrue(responseString.contains("Content-Type: multipart/form-data;"));
assertTrue(contentTypeInHeader.contains("Content-Type: multipart/form-data;"));
System.out.println(responseString);
System.out.println("POST Content Type: " + contentTypeInHeader);
inputStream.close();
try(CloseableHttpClient client = HttpClientBuilder.create()
.build();
CloseableHttpResponse response = (CloseableHttpResponse) client
.execute(post, new CustomHttpClientResponseHandler())){
final int statusCode = response.getCode();
final String responseString = getContent(response.getEntity());
final String contentTypeInHeader = getContentTypeHeader();
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
assertTrue(contentTypeInHeader.contains("Content-Type: multipart/form-data;"));
System.out.println(responseString);
System.out.println("POST Content Type: " + contentTypeInHeader);
inputStream.close();
}
}
@Test
public final void givenCharArrayandText_whenUploadwithAddBinaryBodyandAddTextBody_ThenNoException() throws IOException {
void givenCharArrayandText_whenUploadwithAddBinaryBodyandAddTextBody_ThenNoException() throws IOException {
final String message = "This is a multipart post";
final byte[] bytes = "binary code".getBytes();
final MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.setMode(HttpMultipartMode.STRICT);
builder.addBinaryBody("file", bytes, ContentType.DEFAULT_BINARY, TEXTFILENAME);
builder.addTextBody("text", message, ContentType.TEXT_PLAIN);
final HttpEntity entity = builder.build();
post.setEntity(entity);
response = client.execute(post);
final int statusCode = response.getStatusLine()
.getStatusCode();
final String responseString = getContent();
final String contentTypeInHeader = getContentTypeHeader();
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
// assertTrue(responseString.contains("Content-Type: multipart/form-data;"));
assertTrue(contentTypeInHeader.contains("Content-Type: multipart/form-data;"));
System.out.println(responseString);
System.out.println("POST Content Type: " + contentTypeInHeader);
try(CloseableHttpClient client = HttpClientBuilder.create()
.build();
CloseableHttpResponse response = (CloseableHttpResponse) client
.execute(post, new CustomHttpClientResponseHandler())){
final int statusCode = response.getCode();
final String responseString = getContent(response.getEntity());
final String contentTypeInHeader = getContentTypeHeader();
assertThat(statusCode, equalTo(HttpStatus.SC_OK));
assertTrue(contentTypeInHeader.contains("Content-Type: multipart/form-data;"));
System.out.println(responseString);
System.out.println("POST Content Type: " + contentTypeInHeader);
}
}
// UTIL
private String getContent() throws IOException {
rd = new BufferedReader(new InputStreamReader(response.getEntity()
.getContent()));
private String getContent(HttpEntity httpEntity) throws IOException {
rd = new BufferedReader(new InputStreamReader(httpEntity.getContent()));
String body = "";
StringBuilder content = new StringBuilder();
while ((body = rd.readLine()) != null) {
content.append(body).append("\n");
content.append(body)
.append("\n");
}
return content.toString().trim();
return content.toString()
.trim();
}
private String getContentTypeHeader() throws IOException {
private String getContentTypeHeader() {
return post.getEntity()
.getContentType()
.toString();
.getContentType();
}
}

View File

@ -0,0 +1,11 @@
package com.baeldung.httpclient.handler;
import org.apache.hc.core5.http.ClassicHttpResponse;
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
public class CustomHttpClientResponseHandler implements HttpClientResponseHandler<ClassicHttpResponse> {
@Override
public ClassicHttpResponse handleResponse(ClassicHttpResponse response) {
return response;
}
}