Am 2021-11-08 um 15:00 schrieb Oleg Kalnichevski:


On 11/8/2021 2:47 PM, Michael Osipov wrote:
Am 2021-11-08 um 10:29 schrieb Oleg Kalnichevski:
Folks

Now that HttpClient 5.2 runs I would like to deprecate a decade old way of handling responses in favor of HttpClientResponseHandler functional interface approach:


This common pattern should be discouraged going forward
```
try (final CloseableHttpResponse response = httpclient.execute(httppost)) {
     System.out.println("----------------------------------------");
     System.out.println(response.getCode() + " " + response.getReasonPhrase());
     System.out.println(EntityUtils.toString(response.getEntity()));
}
```
and be replaced by this one:

```
httpclient.execute(httppost, response -> {
     System.out.println("----------------------------------------");
     System.out.println(response.getCode() + " " + response.getReasonPhrase());
     System.out.println(EntityUtils.toString(response.getEntity()));
     return null;
});
```

There are several advantages to the functional interface based approach:

1. it eliminates the entire class of resource leaks due sloppy exception handling in the application code.

2. it would make it easier to implement a classic i/o compatibility layer on top of the async APIs should we ever decide to build such a thing.

On the downside some users might not like the fact that they would need to adjust their existing HTTP response handling logic, but that is the case with all new things.

Please let me know what you think.

Generally, I think this is a good move for most cases, but how these cases/questions you be handled:
* Do I need to return the entire consumed input stream?

One should consume the response message stream inside the handler and return it back to the caller as a higher level domain object

https://github.com/apache/httpcomponents-client/blob/4.5.x/httpclient/src/examples/org/apache/http/examples/client/ClientWithResponseHandler.java

This is the same pattern we have been advocating since early days of 4.x. With lambdas it just looks cleaner.


* How is an external consumer supposed to receive the response and stream in in some fashion?

I have a very explicit usecase which has been working for me and I don't know whether it will continue to work:

===> client (via SOAP or REST GET)  ===> Tomcat, issue GET to upstream => file from response streamed => client

In this case my code in Tomcat acts like a reverse proxy with a lot of custom logic and the CloseableHttpResponse is passed as as I SOAP DataSource/DataHandler and JAX-WS Metro/JAX-RS Jersey do the rest.


Not much different, just your code gets executed inside a closure and no longer needs to explicitly close the response object.

Well, that is going to be a problem because the code in the low level method looks like this:

CloseableHttpResponse downloadResponse = httpClient.execute(downloadFile);

DataHandler dh = new DataHandler(new InputStreamDataSource(new 
HttpResponseInputStream(
                downloadResponse)));

dh is passed on to the return object and a high level class is processing the response implicitly. I don't see way to make that work in a closure.

M

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to