下载文件时,来自 restTemplate 的响应正文被截断

response body from restTemplate is getting truncated when downloading a file

我正在使用 spring RestTemplate 下载文件。文件很小。 我想获得 base64 编码的字符串。但我看到 base64 编码的字符串被截断了。

这是我的代码

RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(
                new ByteArrayHttpMessageConverter());


        StreamResourceReader reader = new StreamResourceReader();
        restTemplate.execute(uri, HttpMethod.POST, null,
                new StreamResponseExtractor(reader));
        return reader.getEncodedString();

StreamResourceReader.java

public class StreamResourceReader  {

    private String encodeString;


    public void read(InputStream content) {
        try {
            encodeString = Base64.encodeBase64String(IOUtils.toByteArray(content));
        } catch (IOException e) {
            throw new IllegalStateException(e);
        }
    }

    public ByteArrayOutputStream getOutputStream(){
        return outputStream;
    }

    public String getEncodedString() {
        return encodeString;
    }
}

StreamResponseExtractor.java

public class StreamResponseExtractor implements ResponseExtractor<InputStream> {

    private StreamResourceReader reader;

    public StreamResponseExtractor(StreamResourceReader resourceReader) {
        this.reader=resourceReader;
    }

    @Override
    public InputStream extractData(ClientHttpResponse response) throws IOException {
        reader.read(response.getBody());
        return null;
   }
}

编辑 刚刚发现 inputStream 被截断了。我不知道为什么以及修复方法是什么。如有任何帮助,我们将不胜感激。

谢谢

要确认您的输入流是否确实被截断,您可以尝试一些操作。 IOUtils.toByteArray(content) 所做的是在内部缓冲输入流的内容和 returns 缓冲区。您可以将缓冲区数组的长度与文件实际表示的字节数组进行比较。您可以使用以下代码

String filePath = "/test.txt";
byte[] fileByteArray= Files.readAllBytes(Paths.get(filePath));

ClientHttpResponse(http 响应的客户端视图)也有可用的输入流,您可以检查内容。

InputStream getBody() throws IOException;

作为对这种情况的测试,我使用 Rest 模板(使用您共享的代码)创建了 spring 启动 Rest 客户端,并使用 Spring Boot 再次创建了文件下载服务。在比较来自下载和直接文件访问的基本编码字符串时,两者 return 相同的内容(使用 String equals 方法进行比较)。

更新:另一件值得尝试的事情就是使用java.net.HttpURLConnection 在一个简单的程序中(有关帮助,请参阅 here)并尝试下载内容并检查它是否正常工作,因为在所有 Spring 抽象背后,在这种情况下使用的基础对象是 HttpURLConnection只有

SimpleClientHttpResponse extends AbstractClientHttpResponse {

public InputStream getBody() throws IOException {
        InputStream errorStream = this.connection.getErrorStream();
        this.responseStream = (errorStream != null ? errorStream : this.connection.getInputStream());
        return this.responseStream;
    }

...........
...........
}

如果这也给您同样的问题,那么是时候查看服务器端了。可能是服务器没有发送完整的数据。