I/O error while reading input message; nested exception is java.io.IOException: Stream closed
遇到“I/O error while reading input message; nested exception is java.io.IOException: Stream closed”错误通常意味着在尝试读取输入流时,该流已经被关闭。这可能是由于多种原因导致的,下面我会详细说明一些可能的原因及解决方法。
可能的原因
-
多次调用InputStream:
request.getInputStream()或类似的流只能被读取一次,如果试图多次读取同一个输入流,将会导致这个异常 。 -
多个@RequestBody注解:在Spring框架中,一个Controller方法不能包含多个
@RequestBody注解,因为这会导致多次尝试读取请求体,从而引起流关闭的异常 。 -
多余的流关闭操作:如果你在程序的不同地方对同一个流执行了多次关闭操作(如在try块和finally块中都关闭了流),也会触发此异常 。
-
不一致的数据类型:有时候,这个问题也可能是由于接口返回类型不一致导致的,比如预期的是JSON格式,但实际上接收到的数据不符合预期 。
解决方案
对于多次调用InputStream的情况:
你可以创建一个包装类来包裹原始的HttpServletRequest,并重写其getInputStream()方法,使得每次调用都返回一个新的InputStream实例,而不是使用已经被关闭的原始流。以下是一个简单的示例:
public class CachingRequestWrapper extends HttpServletRequestWrapper {
private byte[] cachedBody;
public CachingRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
InputStream inputStream = request.getInputStream();
this.cachedBody = inputStream.readAllBytes(); // 缓存输入流数据
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(cachedBody);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return byteArrayInputStream.read();
}
// 必须覆盖的方法...
};
}
}
然后,在你的过滤器或者控制器中使用这个包装后的请求对象。
多个@RequestBody注解的问题:
确保你的控制器方法只有一个@RequestBody注解。如果有多个参数需要从请求体中获取,可以将这些参数封装到一个单独的对象中,然后将这个对象作为@RequestBody的参数 。
例如:
class Args {
private List<String> name1;
private List<String> name2;
// getters and setters...
}
@PostMapping("/saveBody")
public String saveBody(@RequestBody Args args) {
// 业务逻辑
return "保存Body成功";
}
针对多余流关闭操作:
确保不要在代码中多次关闭相同的流。如果在一个finally块中关闭了流,那么在其他地方就不应该再有关闭流的操作 。
以上就是针对“I/O error while reading input message; nested exception is java.io.IOException: Stream closed”问题的一些常见原因和解决方案。根据你的具体情况,可能需要采取不同的措施来解决问题。如果你遇到了上述未涵盖的具体情况,请提供更多的上下文信息以便进一步帮助你。
更多推荐

所有评论(0)