【问题标题】:response body from restTemplate is getting truncated when downloading a file下载文件时来自restTemplate的响应正文被截断
【发布时间】:2017-09-20 22:30:48
【问题描述】:

我正在使用 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 被截断了。我不知道为什么以及修复方法是什么。如有任何帮助,我们将不胜感激。

谢谢

【问题讨论】:

  • @SotiriosDelimanolis 有什么想法吗?

标签: spring-mvc spring-boot resttemplate


【解决方案1】:

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

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

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

InputStream getBody() throws IOException;

作为对此场景的测试,我使用 Rest Template(使用您共享的代码)创建了 Spring Boot Rest 客户端,并使用 Spring Boot 再次创建了文件下载服务。在比较下载和直接文件访问的基本编码字符串时,两者都返回相同的内容(使用Stringequals 方法比较)。

更新:另一件值得尝试的事情就是使用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;
    }

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

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

【讨论】:

  • 是的,我确实使用 IOUtils.toByteArray 进行了比较,并确认 inputStream 被截断。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-28
  • 1970-01-01
  • 2012-12-16
  • 1970-01-01
  • 2018-07-06
相关资源
最近更新 更多