CloseableHttpClient execute call results in NoSuchElementException

68 views Asked by At

Hi team: I have a question regarding the use of Apache HttpClient 5 CloseableHttpClient in a Spring Boot 3 application. I am executing the following code:

        try
        {
            final HttpGet httpGet = new HttpGet("http://httpbin.org/get");
            httpGet.addHeader("content-type", "application/json");
            HttpClientResponseHandler<String> responseHandler = new HttpClientResponseHandler<String>()
            {
                @Override
                public String handleResponse(ClassicHttpResponse _httpResponse) throws HttpException, IOException 
                {
                    int status = _httpResponse.getCode();
                    if (status >= 200 && status < 300)
                    {
                        HttpEntity entity = _httpResponse.getEntity();
                        String stringEntity = EntityUtils.toString(entity);
                        return entity != null ? stringEntity : null;
                    }
                    else
                    {
                        throw new ClientProtocolException("Unexpected response status: " + status);
                    }
                }
            };
            responseBody = closeableHttpClient.execute(httpGet, responseHandler);
            log.info("Response Body: " + responseBody);
        }
        catch (NoSuchElementException _e)
        {
            log.error("NoSuchElementException: "+ _e.getMessage());
            _e.printStackTrace();
        }
        catch (ClientProtocolException _e)
        {
            log.error("ClientProtocolException: "+ _e.getMessage());
        }
        catch (IOException _e)
        {
            log.error("IOException: "+ _e.getMessage());
        }
        catch (Exception _e)
        {
            log.error("Exception: "+ _e.getMessage());
        }

But when I execute this code, I get the following exception:

NoSuchElementException: No more header elements available java.util.NoSuchElementException: No more header elements available

To get the CloseableHttpClient, I have the following configurations:

@Slf4j
@Configuration
@EnableScheduling
public class HttpConfig
    @Bean
    @ConditionalOnMissingBean
    public CloseableHttpClient httpClient(HttpClientConnectionManager connectionManager)
    {
        RequestConfig requestConfig = RequestConfig.custom()
            .setConnectionRequestTimeout(Timeout.ofMilliseconds(15000))
            .setResponseTimeout(Timeout.ofMilliseconds(15000))
            .build();

        return HttpClients.custom()
            .setConnectionManager(connectionManager)
            .setKeepAliveStrategy(getConnectionKeepAliveStrategy())
            .setDefaultRequestConfig(requestConfig)
            .build();
    }

    @Bean(destroyMethod = "")
    @ConditionalOnMissingBean
    public HttpClientConnectionManager httpClientConnectionManager()
    {
        HttpHost host1 = new HttpHost("httpbin.org/get", 80);
        final PoolingHttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create()
                .setConnectionFactory(getHttpConnectionFactory())
                .setPoolConcurrencyPolicy(PoolConcurrencyPolicy.STRICT)
                .setConnPoolPolicy(PoolReusePolicy.LIFO)
                .build();

        connectionManager.setMaxTotal(100);
        connectionManager.setDefaultMaxPerRoute(20);
        connectionManager.setMaxPerRoute(new HttpRoute(host1), 10);

        return connectionManager;
    }
    
    public ConnectionKeepAliveStrategy getConnectionKeepAliveStrategy()
    {
        final ConnectionKeepAliveStrategy connectionKeepAliveStrategy = new ConnectionKeepAliveStrategy()
        {
            @Override
            public TimeValue getKeepAliveDuration(HttpResponse response, HttpContext context)
            {
                Args.notNull(response, "HTTP response");
                final Iterator<HeaderElement> iterator = MessageSupport.iterate(response, HeaderElements.KEEP_ALIVE);
                final HeaderElement headerElement = iterator.next();
                final String param = headerElement.getName();
                final String value = headerElement.getValue();
                if (value != null && param.equalsIgnoreCase("timeout"))
                {
                    try
                    {
                        return TimeValue.ofSeconds(Long.parseLong(value));
                    }
                    catch (final NumberFormatException e)
                    {
                        log.error("Connection Keep-Alive Strategy: Number Format Exception: Safely Ignore: " + e.getMessage());
                    }
                }
                return TimeValue.ofSeconds(5);
            }

        };
        return connectionKeepAliveStrategy; 
    }

    @Bean
    public Runnable getIdleConnectionMonitor(final PoolingHttpClientConnectionManager connectionManager)
    {
        return new Runnable()
        {
            @Override
            @Scheduled(fixedDelay = 15000)
            public void run()
            {
                try
                {
                    if (connectionManager != null)
                    {
                        connectionManager.closeExpired();
                        connectionManager.closeIdle(Timeout.ofSeconds(60000));
                    }
                }
                catch (Exception e)
                {
                    log.error("IdleConnectionMonitor - Exception occurred: Message = {}, Exception = {}", e.getMessage(), e);
                }
            }
        };
    }

I have no idea what could be wrong here. Any help would be much appreciated.

0

There are 0 answers