In existing project I have an HTTP service that fetches data using Apache's HttpClient 4 and returns response InputStream like in this code example:
public class HttpClient4Demo {
public static void main(String[] args) throws IOException {
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
try (Scanner scanner = new Scanner(fetchData(httpClient))) {
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
}
}
}
private static InputStream fetchData(HttpClient httpClient) throws IOException {
HttpResponse response = httpClient.execute(new HttpGet(
"https://dummyjson.com/products/1"
));
return response.getEntity().getContent();
}
}
I want to migrate that service to Apache's HttpClient 5, so I have to rewrite the code:
public class HttpClient5Demo {
public static void main(String[] args) throws IOException {
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
try (Scanner scanner = new Scanner(fetchData(httpClient))) {
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
}
}
}
private static InputStream fetchData(HttpClient httpClient) throws IOException {
ClassicHttpResponse response = httpClient.executeOpen(
null,
new HttpGet("https://dummyjson.com/products/1"),
null
);
return response.getEntity().getContent();
}
}
But that code gives me a warning because ClassicHttpResponse is used without try-with-resources.
If I wrap ClassicHttpResponse with try-with-resources, I'll get a closed InputStream, so I won't be able to read response data.
private static InputStream fetchData(HttpClient httpClient) throws IOException {
try (ClassicHttpResponse response = httpClient.executeOpen(
null,
new HttpGet("https://dummyjson.com/products/1"),
null
)) {
return response.getEntity().getContent();
}
}
I can additionally wrap response.getEntity() into ByteArrayInputStream, and I will get a valid InputStream, but it's not a perfect solution, since the whole response data will be stored in RAM.
private static InputStream fetchData(HttpClient httpClient) throws IOException {
try (ClassicHttpResponse response = httpClient.executeOpen(
null,
new HttpGet("https://dummyjson.com/products/1"),
null
)) {
return new ByteArrayInputStream(EntityUtils.toByteArray(response.getEntity()));
}
}
So is there any way to get response InputStream without closing it and/or storing it in RAM using HttpClient 5?