Java 如何使用restTemplate获得真正的http代码和响应正文?

Java 如何使用restTemplate获得真正的http代码和响应正文?,java,spring,http,resttemplate,http-status-codes,Java,Spring,Http,Resttemplate,Http Status Codes,我有以下代码: LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<>(); FileSystemResource fileSystemResource = new FileSystemResource(fileNameWithPath); map.add("file", fileSystemResource); map.add("type", fileTy

我有以下代码:

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)
但当我以同样的方式在postman中修改url时,我看到404错误:

我希望有像《邮递员》一样的回应和像《邮递员》一样的回应

如果我提供的是
文件
而不是
文件系统资源
,我会得到正确的
HttpStatusException
,在那里我可以提取所需的数据:

catch (HttpStatusCodeException e) {          
            String response = e.getResponseBodyAsString();
            logger.error("Error during attachment push for file: {}, responseText: {}", fileNameWithPath, response, e);
}
如何编写通用代码来提取
响应
httpStatusCode

P.S.1。 RestTemplate初始化:

CloseableHttpClient httpClient
                = HttpClients.custom()
                .setSSLHostnameVerifier(new NoopHostnameVerifier())
                .build();
        HttpComponentsClientHttpRequestFactory requestFactory
                = new HttpComponentsClientHttpRequestFactory();
        requestFactory.setHttpClient(httpClient);
        restTemplate = new RestTemplate(requestFactory);
P.S.2 我已经看过了,但看起来已经在使用建议的工厂了

P.S.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();
        }

但结果是相同的-
套接字写入错误

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

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

org.springframework.web.client.ResourceAccessException:上的I/O错误 发布对“”的请求: 软件导致连接中止:套接字写入错误;嵌套异常 是java.net.SocketException:软件导致的连接中止:套接字 写入错误

阅读异常消息。原因(您省略了stacktrace)是一个
java.net.SocketException
,它的底层是一个

您从未收到响应,因为您可能从未完成发送请求。请参阅相关问题,了解原因


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


我通常使用这种模式,可能对你有用

try{
    ResponseEntity<String> responseEntity = restTemplate.exchange(url, httpMethod, httpEntity, String.class);
    HttpStatus.Series responseSeries = responseEntity.getStatusCode().series();
    if(!HttpStatus.Series.SERVER_ERROR.equals(responseSeries)){
        return responseEntity;
    }
}
catch(HttpClientErrorException e){
    //handle exception here
    //Response received from server: {} ", e.getResponseBodyAsString());
}
catch (RestClientException e) {
    //handle exception here
}
catch (Exception e) {
    //handle exception here
}
试试看{
ResponseEntity ResponseEntity=restTemplate.exchange(url、httpMethod、httpEntity、String.class);
HttpStatus.Series responseSeries=responseEntity.getStatusCode().Series();
如果(!HttpStatus.Series.SERVER_ERROR.equals(responseSeries)){
返回响应性;
}
}
捕获(HttpClientErrorE异常){
//在这里处理异常
//从服务器收到的响应:{},例如getResponseBodyAsString());
}
捕获(RestClientException e){
//在这里处理异常
}
捕获(例外e){
//在这里处理异常
}

“如果我提供的是File而不是FileSystemResource,我会得到正确的HttpStatusException,在这里我可以提取所需的数据”,那么为什么不使用它呢?您可以调用.getFile()获取底层文件对象。@eis,我使用它,但如果我提供了错误的url,我会得到另一个异常-org.springframework.web.client.resourceAccessException现在你反驳了。你刚刚写道,如果使用文件,你会得到正确的HttpStatusException?@eis,你是正确的。如果url错误,我还会得到另一个异常我不支持llowing。如果使用File,如果得到正确的异常,会出现什么问题?因为您没有提供实际的异常详细信息,所以没什么可说的。-您需要哪些详细信息?@gstackoverflow SocketException的stacktrace。将完整stacktrace添加到topic@gstackoverflow那是另一个,上面写着““管道破裂”,而不是“软件导致的连接中断”。这个答案可能会说“如果存在http响应,您可以按照您已经在做的方式获取头文件-但是,您遇到的情况是没有响应,因为在提供此类响应之前连接中断“这和你说的基本上是一样的,只是为了让未来的读者更清楚。向上投票赞成指出此处的实际问题。这无助于解决问题中描述的问题。问题在于没有捕获异常,问题在于抛出的异常不包含HTTP响应。
try{
    ResponseEntity<String> responseEntity = restTemplate.exchange(url, httpMethod, httpEntity, String.class);
    HttpStatus.Series responseSeries = responseEntity.getStatusCode().series();
    if(!HttpStatus.Series.SERVER_ERROR.equals(responseSeries)){
        return responseEntity;
    }
}
catch(HttpClientErrorException e){
    //handle exception here
    //Response received from server: {} ", e.getResponseBodyAsString());
}
catch (RestClientException e) {
    //handle exception here
}
catch (Exception e) {
    //handle exception here
}