如何用WireMock模拟返回InputStream的接口?
解决WireMock模拟PDF流接口时的
ConnectionClosedException问题 我来帮你搞定这个问题——你碰到的Premature end of chunk coded message body错误,本质是WireMock默认的响应编码和客户端读取流的逻辑不匹配导致的。下面给你拆解原因和解决办法:
问题根源
当你直接用withBody(pdfFile)传入字节数组时,WireMock会默认启用分块传输编码(Chunked Transfer Encoding),但你的客户端在读取InputStream时,没有正确处理分块编码的收尾逻辑,就会触发连接提前关闭的报错。
正确的模拟方案
这里有两种可靠的解决方式,你可以根据场景选择:
方案1:禁用分块编码,指定Content-Length
显式设置响应的Content-Length头,让WireMock跳过分块编码,这样客户端就能正常读取流了:
byte[] pdfFile = Files.readAllBytes(Paths.get(ClassLoader.getSystemResource("file.pdf").toURI())); stubFor( get(urlPathMatching(mockPath)) .withHeader("Authorization", equalTo(mockedToken)) .willReturn(aResponse() .withStatus(200) .withHeader("Content-Type", "application/pdf") // 务必设置正确的内容类型 .withHeader("Content-Length", String.valueOf(pdfFile.length)) // 关键:指定内容长度 .withBody(pdfFile)));
方案2:直接传入InputStream返回响应
如果你不想手动计算内容长度,可以直接把PDF文件的InputStream传给WireMock,它会自动处理正确的响应头和编码:
InputStream pdfStream = ClassLoader.getSystemResourceAsStream("file.pdf"); stubFor( get(urlPathMatching(mockPath)) .withHeader("Authorization", equalTo(mockedToken)) .willReturn(aResponse() .withStatus(200) .withHeader("Content-Type", "application/pdf") .withBody(pdfStream))); // 直接传入InputStream
额外注意事项
- 一定要设置
Content-Type为application/pdf,避免客户端对响应内容类型产生误解。 - 如果你的客户端基于Apache HttpClient实现,上面的方案已经完全规避了分块编码带来的问题,不需要额外调整客户端配置。
内容的提问来源于stack exchange,提问作者Rafael A P Nascimento
相关产品推荐
相关产品推荐

