gpt4 book ai didi

java - 如何使用 restTemplate 获取真实的 http 代码和响应主体?

转载 作者:可可西里 更新时间:2023-11-01 16:13:01 38 4
gpt4 key购买 nike

我有以下代码:

LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<>();

FileSystemResource fileSystemResource = new FileSystemResource(fileNameWithPath);
map.add("file", fileSystemResource);
map.add("type", fileType);
map.add("org_id", systemSettingsService.getSystemSettings().getOrganizationId());
map.add("stone_id", stoneId);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity = new HttpEntity<>(map, headers);

restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class)

如果我提供的所有参数都正确 - enpoint 会像 Postman 应用程序一样返回 200 个 http 状态代码。

但是如果我提供了错误的 url - 我会看到异常:

 org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://external_server/api/v1/push_file1": Broken pipe (Write failed); nested exception is java.net.SocketException: Broken pipe (Write failed)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:666)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:531)
at com.pack.GenericDataServiceImpl.pushAttachment(GenericDataServiceImpl.java:311)
at com.pack.FailedAttachmentPushReSender.retryFailedPushes(FailedAttachmentPushReSender.java:24)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
at java.util.concurrent.Executors$RunnableAdapter.call$$$capture(Executors.java:511)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java)
at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
at java.util.concurrent.FutureTask.run(FutureTask.java)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748) Caused by: java.net.SocketException: Broken pipe (Write failed)
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)
at java.net.SocketOutputStream.write(SocketOutputStream.java:155)
at sun.security.ssl.OutputRecord.writeBuffer(OutputRecord.java:431)
at sun.security.ssl.OutputRecord.write(OutputRecord.java:417)
at sun.security.ssl.SSLSocketImpl.writeRecordInternal(SSLSocketImpl.java:886)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:857)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123)
at org.apache.http.impl.io.SessionOutputBufferImpl.streamWrite(SessionOutputBufferImpl.java:124)
at org.apache.http.impl.io.SessionOutputBufferImpl.write(SessionOutputBufferImpl.java:160)
at org.apache.http.impl.io.ContentLengthOutputStream.write(ContentLengthOutputStream.java:113)
at org.apache.http.entity.ByteArrayEntity.writeTo(ByteArrayEntity.java:114)
at org.apache.http.impl.DefaultBHttpClientConnection.sendRequestEntity(DefaultBHttpClientConnection.java:156)
at org.apache.http.impl.conn.CPoolProxy.sendRequestEntity(CPoolProxy.java:160)
at org.apache.http.protocol.HttpRequestExecutor.doSendRequest(HttpRequestExecutor.java:238)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:123)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:89)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:652) ... 20 more

但是当我以同样的方式修改 postman 中的 url 时 - 我看到 404 错误:

enter image description here

我想要像 postman 一样的回复和像 postman 一样的回复。

如果我提供 File 而不是 FileSystemResource 我会得到正确的 HttpStatusException 我可以在其中提取我想要的数据:

catch (HttpStatusCodeException e) {          
String response = e.getResponseBodyAsString();
logger.error("Error during attachment push for file: {}, responseText: {}", fileNameWithPath, response, e);
}

如何编写提取responsehttpStatusCode 的通用代码?

附注1.

RestTemplate 初始化:

CloseableHttpClient httpClient
= HttpClients.custom()
.setSSLHostnameVerifier(new NoopHostnameVerifier())
.build();
HttpComponentsClientHttpRequestFactory requestFactory
= new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
restTemplate = new RestTemplate(requestFactory);

附言2

我读过 RestTemplate ClientHttpResponse.getBody() throws I/O Error但看起来已经使用了建议的工厂

附注3

我试过这个:

CloseableHttpClient client = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(buildAttachmentPushUrl());

MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addBinaryBody("file", fileSystemResource.getFile(), ContentType.APPLICATION_OCTET_STREAM, fileSystemResource.getFilename());
builder.addTextBody("type", fileType);
builder.addTextBody("org_id", systemSettingsService.getSystemSettings().getOrganizationId());
builder.addTextBody("stone_id", stoneId);

HttpEntity multipart = builder.build();

httpPost.setEntity(multipart);

CloseableHttpResponse response = client.execute(httpPost);
logger.info("response code {}", response.getStatusLine().getStatusCode());

client.close();
} catch (IOException e) {
e.printStackTrace();
}

但结果相同 - socket write error

最佳答案

如何使用 restTemplate 获取真正的 http 代码和响应主体?

简短的回答是你不能,因为没有。

org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://external_server.ventures/api/v1/push_file1": Software caused connection abort: socket write error; nested exception is java.net.SocketException: Software caused connection abort: socket write error

阅读异常信息。原因(您省略了堆栈跟踪)是一个 java.net.SocketException 和一个底层 socket write error .

您从未收到回复,因为您可能从未完成发送请求。出于某些原因,请参阅链接的问题。


RestClientResponseException 是您要捕获的内容。它涵盖与您可能收到的响应相关的所有错误,并提供对状态、标题和正文的访问。您抛出的是 ResourceAccessException,它涵盖了所有可能发生但没有任何响应的 I/O 错误。

UML diagram of RestClientException and subclasses

关于java - 如何使用 restTemplate 获取真实的 http 代码和响应主体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48330446/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com