如何解决如何使用 Spring RestTemplate 在 POST 请求上设置超时?
我想在通过 Spring RestTemplate 发送 POST 请求的过程中设置超时。例如,如果请求没有在 X 秒内完成,无论什么原因,如果可能,我希望它抛出异常并停止执行/释放资源。
最初,我尝试使用 HttpComponentsClientHttpRequestFactory,但没有成功并降级为 SimpleClientHttpRequestFactory。现在我只想让它在所有情况下都与 SimpleClientHttpRequestFactory 一起工作,然后尝试更复杂的解决方案。
我有以下配置:
@Bean
public RestTemplate restTemplate() {
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setConnectTimeout(3_000);
requestFactory.setReadTimeout(30_000);
return new RestTemplate(requestFactory);
}
我的用法如下:
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type","text/xml;charset=UTF-8");
httpentity<String> requestEntity = new httpentity<>(xmlMsgAsstring,headers);
ResponseEntity<String> response = restTemplate.postForEntity(url,requestEntity,String.class);
我有一个目标服务器,目前无法访问,我有一堆 XML 消息需要 POST 到该服务器。使用上面的代码,对于大多数消息它按预期工作,它会在 30 秒后抛出以下异常:
org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://X:Y/Z": Read timed out; nested exception is java.net.socketTimeoutException: Read timed out
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:744)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:670)
at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:445)
...
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.net.socketTimeoutException: Read timed out
at java.net.socketInputStream.socketRead0(Native Method)
at java.net.socketInputStream.socketRead(SocketInputStream.java:116)
at java.net.socketInputStream.read(SocketInputStream.java:171)
at java.net.socketInputStream.read(SocketInputStream.java:141)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:735)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:678)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1593)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1498)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
at org.springframework.http.client.SimpleClientHttpResponse.getRawStatusCode(SimpleClientHttpResponse.java:55)
at org.springframework.web.client.DefaultResponseErrorHandler.hasError(DefaultResponseErrorHandler.java:55)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:766)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:736)
... 18 common frames omitted
但是,对于一条特定的消息,它会卡住约 955 秒,然后抛出以下异常:
org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://X:Y/Z": Unexpected end of file from server; nested exception is java.net.socketException: Unexpected end of file from server
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:744)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:670)
at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:445)
...
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.net.socketException: Unexpected end of file from server
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:851)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:678)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1593)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1498)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
at org.springframework.http.client.SimpleClientHttpResponse.getRawStatusCode(SimpleClientHttpResponse.java:55)
at org.springframework.web.client.DefaultResponseErrorHandler.hasError(DefaultResponseErrorHandler.java:55)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:766)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:736)
... 26 common frames omitted
前一条30秒后成功抛出的消息和最后一条是类似的XML消息,目标相同。我想到的唯一区别是消息的大小,最后一个是~204KB,而以前的所有消息都小得多。为什么会出现最后一个异常,这种情况下如何设置时间限制?
在 Jetty 上运行的 Spring Boot 2.1.10
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。