Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[HttpClient] Refactor BodyContent to be an interface
  • Loading branch information
rbygrave committed Oct 5, 2023
commit 574d47729e9ca7524789082a20e7294adb49ec26
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import io.avaje.http.client.BodyAdapter;
import io.avaje.http.client.BodyContent;
import io.avaje.http.client.BodyReader;
import io.avaje.http.client.BodyWriter;
import io.avaje.http.client.*;

import java.io.*;
import java.util.List;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,6 @@ void listReader() {
}

BodyContent content(String raw) {
return new BodyContent("not-used", raw.getBytes());
return BodyContent.of(raw.getBytes());
}
}
51 changes: 33 additions & 18 deletions http-client/src/main/java/io/avaje/http/client/BodyContent.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,55 @@
* <p>
* This is not used for streaming content.
*/
public class BodyContent {
public interface BodyContent {

public static final String JSON_UTF8 = "application/json; charset=UTF-8";
/**
* Create BodyContent with the given byte[] content.
*/
static BodyContent of(byte[] content) {
return new DBodyContent(content);
}

private final String contentType;
/**
* Create BodyContent with the given string content.
*/
static BodyContent of(String content) {
return new DBodyContentS(null, content);
}

private final byte[] content;
/**
* Create BodyContent with the given the content type and string content.
*/
static BodyContent of(String contentType, String content) {
return new DBodyContentS(contentType, content);
}

/**
* Create and return as JSON body content given raw content.
* Create BodyContent with the given the content type and byte[] content.
*/
public static BodyContent asJson(byte[] content) {
return new BodyContent(JSON_UTF8, content);
static BodyContent of(String contentType, byte[] content) {
return new DBodyContent(contentType, content);
}

/**
* Create with content type and content.
* Create BodyContent for JSON byte[] content.
*/
public BodyContent(String contentType, byte[] content) {
this.contentType = contentType;
this.content = content;
static BodyContent asJson(byte[] content) {
return DBodyContent.asJson(content);
}

/**
* Return the content type.
*/
public String contentType() {
return contentType;
}
String contentType();

/**
* Return the raw content.
* Return the content as bytes.
*/
public byte[] content() {
return content;
}
byte[] content();

/**
* Return the content as UTF8 string.
*/
String contentAsUtf8();
}
43 changes: 43 additions & 0 deletions http-client/src/main/java/io/avaje/http/client/DBodyContent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package io.avaje.http.client;

import java.nio.charset.StandardCharsets;

/**
* Bytes based body content.
*/
final class DBodyContent implements BodyContent {

private static final String JSON_UTF8 = "application/json; charset=UTF-8";

private final String contentType;
private final byte[] content;

static BodyContent asJson(byte[] content) {
return new DBodyContent(JSON_UTF8, content);
}

DBodyContent(byte[] content) {
this.content = content;
this.contentType = null;
}

DBodyContent(String contentType, byte[] content) {
this.contentType = contentType;
this.content = content;
}

@Override
public String contentType() {
return contentType;
}

@Override
public byte[] content() {
return content;
}

@Override
public String contentAsUtf8() {
return new String(content, StandardCharsets.UTF_8);
}
}
32 changes: 32 additions & 0 deletions http-client/src/main/java/io/avaje/http/client/DBodyContentS.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package io.avaje.http.client;

import java.nio.charset.StandardCharsets;

/**
* String based body content.
*/
final class DBodyContentS implements BodyContent {

private final String contentType;
private final String content;

DBodyContentS(String contentType, String content) {
this.contentType = contentType;
this.content = content;
}

@Override
public String contentType() {
return contentType;
}

@Override
public byte[] content() {
return content.getBytes(StandardCharsets.UTF_8);
}

@Override
public String contentAsUtf8() {
return content;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,14 @@ BodyContent readErrorContent(boolean responseAsBytes, HttpResponse<?> httpRespon
final String contentType = getContentType(httpResponse);
final Object body = httpResponse.body();
if (body instanceof String) {
return new BodyContent(contentType, ((String) body).getBytes(StandardCharsets.UTF_8));
return BodyContent.of(contentType, (String) body);
}
if (body instanceof Stream) {
var sb = new StringBuilder(50);
for (Object line : ((Stream<Object>) body).collect(Collectors.toList())) {
sb.append(line);
}
return new BodyContent(contentType, sb.toString().getBytes(StandardCharsets.UTF_8));
return BodyContent.of(contentType, sb.toString());
}
final String type = (body == null) ? "null" : body.getClass().toString();
throw new IllegalStateException("Unable to translate response body to bytes? Maybe use HttpResponse directly instead? Response body type: " + type);
Expand All @@ -194,7 +194,7 @@ public BodyContent readContent(HttpResponse<byte[]> httpResponse) {
}
final byte[] bodyBytes = decodeContent(httpResponse);
final String contentType = getContentType(httpResponse);
return new BodyContent(contentType, bodyBytes);
return BodyContent.of(contentType, bodyBytes);
}

String getContentType(HttpResponse<?> httpResponse) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ class DHttpClientRequest implements HttpClientRequest, HttpClientResponse {

private BodyContent encodedRequestBody;
private HttpRequest.BodyPublisher body;
private String rawRequestBody;

private HttpRequest.Builder httpRequest;

Expand Down Expand Up @@ -82,9 +81,6 @@ public String url() {

@Override
public Optional<BodyContent> bodyContent() {
if (rawRequestBody != null) {
return Optional.of(new BodyContent(null, rawRequestBody.getBytes(StandardCharsets.UTF_8)));
}
return Optional.ofNullable(encodedRequestBody);
}

Expand Down Expand Up @@ -328,14 +324,14 @@ public HttpClientRequest body(Object bean, Class<?> type, String contentType) {

@Override
public HttpClientRequest body(String body) {
this.rawRequestBody = body;
this.encodedRequestBody = BodyContent.of(body);
this.body = HttpRequest.BodyPublishers.ofString(body);
return this;
}

@Override
public HttpClientRequest body(byte[] bytes) {
this.encodedRequestBody = new BodyContent(null, bytes);
this.encodedRequestBody = BodyContent.of(bytes);
return this;
}

Expand Down Expand Up @@ -838,11 +834,9 @@ public String requestBody() {
if (suppressLogging) {
return "<suppressed request body>";
} else if (encodedRequestBody != null) {
return new String(encodedRequestBody.content(), StandardCharsets.UTF_8);
return encodedRequestBody.contentAsUtf8();
} else if (bodyFormEncoded) {
return buildEncodedFormContent();
} else if (rawRequestBody != null) {
return rawRequestBody;
} else if (body != null) {
return body.toString();
} else {
Expand Down
2 changes: 1 addition & 1 deletion tests/test-jex/src/main/resources/public/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"version" : ""
},
"paths" : {
"/" : {
"" : {
"get" : {
"tags" : [

Expand Down