PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(2000);
connectionManager.setDefaultMaxPerRoute(500);
RequestConfig config = RequestConfig.custom().setConnectionRequestTimeout(10000).setConnectTimeout(10000)
.setSocketTimeout(10000).build();
CloseableHttpClient httpClient = HttpClientBuilder.create().setConnectionManager(connectionManager)
.setDefaultRequestConfig(config).build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
// HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setConnectTimeout(10000);
requestFactory.setReadTimeout(10000);
requestFactory.setConnectionRequestTimeout(10000);
RestTemplate restTemplate = new RestTemplate(requestFactory);
When we call a API which responds with Response status and Reason Phrase
HTTP/1.1 200 OK
This breaks as following
Caused by: org.apache.http.ProtocolException: Invalid header: [0x10][0x11]OK
at org.apache.http.impl.io.AbstractMessageParser.parseHeaders(AbstractMessageParser.java:230)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:266)
at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163)
at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:167)
Related
We are upgrading to springboot 3.0 and we have the following resttemplate code.The following code creating issue at CloseableHttpClient and NoopHostnameVerifier.We are upgrading this app to springboot 3.0.
`
#Bean public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
CloseableHttpClient httpClient = HttpClientBuilder.create().setSSLHostnameVerifier(new NoopHostnameVerifier()) .build();
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory( httpClient);
restTemplate.setRequestFactory(clientHttpRequestFactory);
return restTemplate;
}
`
We are noware found NoopHostnameVerifier,CloseableHttpClient.Any help is appreciated.
Upgrade to spring boot 3
Thanks in Advance
I have a springboot rest Service A calling rest service B using restTemplate.
Rest service A's restTemplate bean is created as follows with timeout settings as seen in the code snippet below.
#Bean
RestTemplate getRestTemplate()
{
CloseableHttpClient closeableHttpClient = HttpClientBuilder.create().build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(closeableHttpClient);
RestTemplate restTemplate = new RestTemplate(requestFactory);
requestFactory.setConnectTimeout( 2000 );
requestFactory.setReadTimeout( 2000 );
return restTemplate;
}
A calls B as follows:
try{
restTemplate.postForEntity(urlSvcB, httpEntity, myObject.class);
}
catch (Exception ex){
.....some code here.....
}
When I put both A and B in bebug mode and wait at a breakpoint in B for more than 2 seconds, I except restTemplate call in A to detect a timeout of 2 seconds and straight away go in to the exception block BUT it doesn't. I also put a thread.sleep(5000) in B but still in vain.
Is there anything wrong I am doing because of which I don't see the expected ?
If you are using spring boot, then you could try:
#Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder)
{
return restTemplateBuilder
.setConnectTimeout(...)
.setReadTimeout(...)
.build();
}
If that is not okay, then in your current code, try setting all the props on requestFactory before creating a restTemplate OR test once by getting rid of CloseableHTTPClient like:
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
httpRequestFactory.setConnectionRequestTimeout(...);
httpRequestFactory.setConnectTimeout(...);
httpRequestFactory.setReadTimeout(...);
return new RestTemplate(httpRequestFactory);
I am using RestTemplate with ConnectionPooling using PoolingHttpClientConnectionManager as in below code :
PoolingHttpClientConnectionManager connectionManager = new
PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(DEFAULT_MAX_TOTAL_CONNECTIONS);
connectionManager.setDefaultMaxPerRoute(DEFAULT_MAX_CONNECTIONS_PER_ROUTE);
connectionManager.setMaxPerRoute(new HttpRoute(new
HttpHost(excConfig.getImsServerEndpoint())), IMS_ROUTE_MAX_CONNECTIONS);
CloseableHttpClient httpclient = HttpClients.custom().setConnectionManager(connectionManager).build();
HttpComponentsClientHttpRequestFactory httpReqFactory = new HttpComponentsClientHttpRequestFactory(httpclient);
httpReqFactory.setReadTimeout(DEFAULT_HTTP_TIMEOUT_MILLISECONDS);
httpReqFactory.setConnectionRequestTimeout(DEFAULT_HTTP_TIMEOUT_MILLISECONDS);
httpReqFactory.setConnectTimeout(DEFAULT_HTTP_TIMEOUT_MILLISECONDS);
restTemplate = new RestTemplate(httpReqFactory);
Does RestTemplate take care of terminating stale connections by itself? Or do I need to put in some specific handling for the same?
By default it does not, but you can configure it easily in your CloseableHttpClient configuration.
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultRequestConfig(RequestConfig.custom().setStaleConnectionCheckEnabled(true))
.setConnectionManager(connectionManager)
.build();`
Source here.
setStaleConnectionCheckEnabled has become obsolete.
HttpClients.custom()
.setDefaultRequestConfig(RequestConfig.custom().setStaleConnectionCheckEnabled(true))
.setConnectionManager(connectionManager)
.build();
In HttpClient 4.5.3 the below code works -
PoolingHttpClientConnectionManager connManager
= new PoolingHttpClientConnectionManager();
connManager.setValidateAfterInactivity(20);
HttpClient httpClient = HttpClients.custom().setConnectionManager(connManager).build();
I want to authenticate NTLM using Rest template , can any one suggest the way ?
If anyone stumble upon this entry again, this is the builtin solution:
Ensure your project includes the org.apache.httpcomponents.httpclient.
Then you can build your RestTemplate with this snippet:
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY, new NTCredentials(user, password, "source-host-name", "domain-name"));
CloseableHttpClient httpClient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider)
.build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
RestTemplate restTemplate = new RestTemplate(requestFactory);
this is what I did taking cues from here. Credits goes here only.
Set up rest template to use apache http client -> compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.5'
Updated my rest template bean to use httpclient -
RestTemplate restTemplate = new RestTemplate();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
restTemplate.setRequestFactory(requestFactory);
Then just do what the link here says. Add the NtlmAuthenticator class and do this just before your restTemplate call.
NtlmAuthenticator authenticator = new NtlmAuthenticator(userName, password);
Authenticator.setDefault(authenticator);
That's it. You are all set up.
This is my Configuration for Rest Template,
#Bean
#Qualifier("myRestService")
public RestTemplate createRestTemplate(#Value("${connection.timeout}") String maxConn) {
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(maxTotalConn);
connectionManager.setDefaultMaxPerRoute(maxPerChannel);
RequestConfig config = RequestConfig.custom().setConnectTimeout(100000).build();
CloseableHttpClient httpClient = HttpClientBuilder.create().setConnectionManager(connectionManager)
.setDefaultRequestConfig(config).build();
ClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
RestTemplate restTemplate = new RestTemplate(factory);
restTemplate.setErrorHandler(new RestResponseErrorHandler());
restTemplate.setMessageConverters(createMessageConverters());
return restTemplate;
}
Am using PoolingHttpClientConnectionManager for managing the connections.
Its being accessed by the following code,
ResponseEntity<String> response = restClient.exchange( url, HttpMethod.GET, entity , String.class );
Do i need to release the connection after the above call or is it taken care by RestTemplate. If we need to take care of releasing connection.
Please can some one explain/show how to release the connection.
You should declare the ClientHttpRequestFactory as a bean. By declaring it as a bean, it becomes managed by the Spring bean factory, which will call the factory's destroy method when the application is closed, or the bean goes out of scope. The destroy method of the ClientHttpRequestFactory will close the underlying ClientConnectionManager's connection pool. You can check the Spring API docs for this.
#Bean
public ClientHttpRequestFactory createRequestFactory(#Value("${connection.timeout}") String maxConn) {
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(maxTotalConn);
connectionManager.setDefaultMaxPerRoute(maxPerChannel);
RequestConfig config = RequestConfig.custom().setConnectTimeout(100000).build();
CloseableHttpClient httpClient = HttpClientBuilder.create().setConnectionManager(connectionManager)
.setDefaultRequestConfig(config).build();
return new HttpComponentsClientHttpRequestFactory(httpClient);
}
Then you can use this bean to create your RestTemplate:
#Bean
#Qualifier("myRestService")
public RestTemplate createRestTemplate(ClientHttpRequestFactory factory) {
RestTemplate restTemplate = new RestTemplate(factory);
restTemplate.setErrorHandler(new RestResponseErrorHandler());
restTemplate.setMessageConverters(createMessageConverters());
return restTemplate;
}
The question which you have asked:
Do i need to release the connection after the above call or is it taken care by RestTemplate. If we need to take care of releasing connection.
No, you do not need to close the connection on the response, if you use resttemplate.
From the apache httpclient, you need to consume the complete response (EntityUtils.consume(HttpEntity) and close the response.
This can be verified in the ClientConnectionRelease.java
But RestTemplate does this for you, to verify the same have a look into
RestTemplate.java
Look for method
protected <T> T doExecute(URI url,...) {
try {
ClientHttpRequest request = this.createRequest(url, method);
...
response = request.execute();
...
if(responseExtractor != null) {
var7 = responseExtractor.extractData(response);
return var7;
}
...
...
} finally {
if(response != null) {
response.close();
}
}
}
Where response extractor does the work for you by consuming the response using
responseExtractor.extractData(response);
And after extracting the data completely it is closing response.close() as well.
I think the answer is here: org.springframework.remoting.httpinvoker.HttpComponentsHttpInvokerRequestExecutor#doExecuteRequest
#Override
protected RemoteInvocationResult doExecuteRequest(
HttpInvokerClientConfiguration config, ByteArrayOutputStream baos)
throws IOException, ClassNotFoundException {
HttpPost postMethod = createHttpPost(config);
setRequestBody(config, postMethod, baos);
try {
HttpResponse response = executeHttpPost(config, getHttpClient(), postMethod);
validateResponse(config, response);
InputStream responseBody = getResponseBody(config, response);
return readRemoteInvocationResult(responseBody, config.getCodebaseUrl());
}
finally {
postMethod.releaseConnection();
}
}