Motivating example: I have an HTTP client whose sole purpose is to produce a single InputStream
. The HTTP client should be closed as soon as the InputStream
is closed. Is there a way to subscribe the HTTP client’s close()
method to the stream’s?
The real problem is doing this generically. I can create a subclass of InputStream
overriding close()
and add httpClient.close()
, but maybe tomorrow I’m facing the same problem but instead of an Http client it’s a file handle, or I need to dispose of multiple resources B, C, D when A closes, and so on. Being able to “subscribe” a closeable resource to another would be ideal, but the API doesn’t seem to support this.
1
Perhaps you could use a pattern similar to spring’s jdbctemplate
Eg
public interface InputStreamCallback<T> {
T apply(InputStream in) throws IOException;
}
public class HttpClientTemplate {
public <T> T get(String url, InputStreamCallback<T> callback) throws IOException {
try (
HttpClient client = new HttpClient();
InputStream responseStream = client.get(url).getResponseStream()
) {
return callback.apply(responseStream );
}
}
public <T> T post(String url, Object postBody, InputStreamCallback<T> callback) throws IOException {
try (
HttpClient client = new HttpClient();
InputStream responseStream = client.post(url, postBody).getResponseStream()
) {
return callback.apply(responseStream );
}
}
}
public class Main {
public static void main(String[] args) {
HttpClientTemplate clientTemplate = new HttpClientTemplate();
InputStreamCallback<String> callback = in -> IOUtils.readString(in);
String responseString = clientTemplate.get("http://example.com", callback);
}
}
This way you’re guaranteed to close everything once you’ve applied the callback