【发布时间】:2021-07-09 14:58:44
【问题描述】:
我有一个在一组产品上循环的程序,并且对于每个产品,都从外部应用程序请求一个 XML。
我尝试使用 Apache HTTP 客户端和 Java-11 HTTP 客户端。两者都会在一定/固定数量的请求后抛出 IOException。此后,此 IOException 会重复多次。之后,请求突然停止抛出 IOExceptions。
奇怪的是,两段代码都在恰好 104 次后开始抛出 IOExceptions。
对于 Apache 方式,错误是处理对 {}->http://somesite:80: Connection reset 的请求时捕获的 I/O 异常(java.net.SocketException)
对于 Java11 方式,是 HTTP/1.1 标头解析器未收到字节/对等方重置连接。
如果我手动尝试下载带有导致问题的 Id 的 XML,则响应正常。
所以,对我来说,我认为外部方关闭了连接或其他东西,但如何防止这种情况发生? 我尝试使用 connecttimeout/connectionrequesttimeouts/sockettimeout 但这并没有解决问题。
谁有解决这个问题的想法或可以解释这里发生了什么?
Apache 变体的代码如下所示,为每个产品/ID 调用方法:
public String ApacheHTTP_getIceCatSpecifications(Integer Id)
{
String list = new ArrayList<String>();
CredentialsProvider provider = new BasicCredentialsProvider();
provider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(env.getProperty("user"), env.getProperty("password")));
HttpGet httpGet = new HttpGet("http://somesite/" + Id + ".xml");
CloseableHttpClient client = HttpClientBuilder.create().setDefaultCredentialsProvider(provider).build();
ICECATInterface product = null;
try (CloseableHttpResponse response = client.execute(httpGet))
{
final HttpEntity entity = response.getEntity();
if (entity != null)
{
InputStream inputStream = entity.getContent()
//list = get from inputstream
}
} catch (ClientProtocolException e)
{
} catch (IOException e)
{
log.error("IOException {}");
}
return list;
}
对于 Java 11 变体:
public List<String> getSpecifications_JAVA11(Integer Id)
{
List<String> specificationList = new ArrayList<String>();
HttpClient client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_1_1)
.authenticator(new Authenticator()
{
@Override
protected PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(
env.getProperty("user"),
env.getProperty("password").toCharArray());
}
})
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://somesite/" + Id + ".xml"))
.build();
HttpResponse<InputStream> response = null;
try
{
response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
// specificationList = read from the response...
} catch (IOException e)
{
e.printStackTrace();
} catch (InterruptedException e)
{
e.printStackTrace();
}
return specificationList;
}
【问题讨论】:
-
这感觉像是服务器正在做的某种节流。您在特定时间范围内发送了太多请求,而服务器告诉您退出。
标签: java httpclient apache-httpclient-4.x