Apache HttpComponents Client fluent API providing a simplified interface for HTTP operations
—
The Response class provides multiple ways to consume HTTP response content with automatic resource management. Each response can only be consumed once.
The Response class offers several methods to consume response content:
public Content returnContent() throws ClientProtocolException, IOException;
public HttpResponse returnResponse() throws IOException;
public void saveContent(File file) throws IOException;
public void discardContent();
public <T> T handleResponse(ResponseHandler<T> handler) throws ClientProtocolException, IOException;Get response content as a reusable Content object:
import org.apache.http.client.fluent.Request;
import org.apache.http.client.fluent.Content;
// Get content as Content object
Content content = Request.Get("https://api.example.com/data")
.execute()
.returnContent();
// Access content in multiple ways
String text = content.asString();
byte[] bytes = content.asBytes();
InputStream stream = content.asStream();Get the underlying HttpResponse for advanced processing:
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.Header;
HttpResponse response = Request.Get("https://api.example.com/data")
.execute()
.returnResponse();
// Access response metadata
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
String reasonPhrase = statusLine.getReasonPhrase();
// Access headers
Header[] headers = response.getAllHeaders();
Header contentType = response.getFirstHeader("Content-Type");Save response content directly to a file:
import java.io.File;
File outputFile = new File("/path/to/output.txt");
Request.Get("https://api.example.com/download")
.execute()
.saveContent(outputFile);The saveContent method:
HttpResponseException for HTTP error status codes (>= 300)Discard response content without processing (useful for HEAD requests or when only status matters):
Request.Head("https://api.example.com/check")
.execute()
.discardContent();Process responses with custom logic using ResponseHandler:
import org.apache.http.client.ResponseHandler;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
// Custom handler to extract specific header
ResponseHandler<String> headerHandler = new ResponseHandler<String>() {
@Override
public String handleResponse(HttpResponse response) throws IOException {
Header locationHeader = response.getFirstHeader("Location");
return locationHeader != null ? locationHeader.getValue() : null;
}
};
String location = Request.Post("https://api.example.com/create")
.bodyString("{\"name\":\"test\"}", ContentType.APPLICATION_JSON)
.execute()
.handleResponse(headerHandler);
// Custom handler to parse JSON (example with manual parsing)
ResponseHandler<Map<String, Object>> jsonHandler = new ResponseHandler<Map<String, Object>>() {
@Override
public Map<String, Object> handleResponse(HttpResponse response) throws IOException {
String json = EntityUtils.toString(response.getEntity());
// Parse JSON manually or with your preferred JSON library
// This is just a placeholder example
return parseJson(json);
}
};The Content class provides a reusable container for response data:
public class Content {
public static final Content NO_CONTENT;
public Content(byte[] raw, ContentType type);
public ContentType getType();
public byte[] asBytes();
public String asString();
public String asString(Charset charset);
public InputStream asStream();
public String toString();
}import org.apache.http.entity.ContentType;
import java.nio.charset.StandardCharsets;
Content content = Request.Get("https://api.example.com/data")
.execute()
.returnContent();
// Get content type information
ContentType contentType = content.getType();
String mimeType = contentType.getMimeType();
Charset charset = contentType.getCharset();
// Access content as different types
byte[] rawBytes = content.asBytes();
String defaultString = content.asString();
String utf8String = content.asString(StandardCharsets.UTF_8);
InputStream stream = content.asStream();
// Content is reusable
String copy1 = content.asString();
String copy2 = content.asString(); // Same content, multiple accesses allowed
// Empty content constant
Content empty = Content.NO_CONTENT;A built-in ResponseHandler implementation that converts HttpResponse messages to Content instances. This class is used internally by the fluent API but can also be used directly for custom response processing.
public class ContentResponseHandler extends AbstractResponseHandler<Content> {
public ContentResponseHandler();
public Content handleEntity(HttpEntity entity) throws IOException;
}The ContentResponseHandler is used internally by returnContent() but can be used explicitly:
import org.apache.http.client.fluent.ContentResponseHandler;
// Explicit usage
Content content = Request.Get("https://api.example.com/data")
.execute()
.handleResponse(new ContentResponseHandler());
// Equivalent to returnContent()
Content sameContent = Request.Get("https://api.example.com/data")
.execute()
.returnContent();Use ContentResponseHandler with Async operations:
import org.apache.http.client.fluent.Async;
import org.apache.http.client.fluent.ContentResponseHandler;
import java.util.concurrent.Future;
Async async = Async.newInstance();
// Use ContentResponseHandler explicitly in async operations
Future<Content> future = async.execute(
Request.Get("https://api.example.com/data"),
new ContentResponseHandler()
);
Content content = future.get();
String response = content.asString();ContentResponseHandler automatically handles HTTP error status codes and entity processing:
try {
ContentResponseHandler handler = new ContentResponseHandler();
Content content = Request.Get("https://api.example.com/data")
.execute()
.handleResponse(handler);
System.out.println("Response: " + content.asString());
} catch (HttpResponseException e) {
System.err.println("HTTP error " + e.getStatusCode() + ": " + e.getMessage());
} catch (IOException e) {
System.err.println("I/O error: " + e.getMessage());
}Each Response object can only be consumed once. After calling any consumption method, the response is marked as consumed:
Response response = Request.Get("https://api.example.com/data").execute();
// First consumption - works
Content content = response.returnContent();
// Second consumption - throws IllegalStateException
try {
response.returnResponse(); // This will fail
} catch (IllegalStateException e) {
System.err.println("Response already consumed: " + e.getMessage());
}Response handling methods can throw:
ClientProtocolException - For HTTP protocol errorsIOException - For I/O errors during response processingHttpResponseException - For HTTP error status codes (thrown by saveContent())IllegalStateException - For attempts to consume already-consumed responsesimport org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpResponseException;
try {
Content content = Request.Get("https://api.example.com/data")
.execute()
.returnContent();
String data = content.asString();
System.out.println("Response: " + data);
} catch (ClientProtocolException e) {
System.err.println("Protocol error: " + e.getMessage());
} catch (IOException e) {
System.err.println("I/O error: " + e.getMessage());
}
// Handling HTTP error status codes with saveContent
try {
Request.Get("https://api.example.com/nonexistent")
.execute()
.saveContent(new File("output.txt"));
} catch (HttpResponseException e) {
System.err.println("HTTP error " + e.getStatusCode() + ": " + e.getMessage());
}returnContent() for text/JSON responses, saveContent() for file downloads, discardContent() when you only need statusreturnResponse() or catch HttpResponseException with saveContent()Install with Tessl CLI
npx tessl i tessl/maven-org-apache-httpcomponents--fluent-hc