输入流只能读取一次,不能重复读取,如果在过滤器或者拦截器中有业务需求对输入流进行一些其他操作,那么此处读取过后再到controller层就会报错,提示IO异常。
自定义Wrapper
class BufferedServletInputStream extends ServletInputStream {
private ByteArrayInputStream inputStream;
private boolean finished = false;
public BufferedServletInputStream(byte[] buffer) {
this.inputStream = new ByteArrayInputStream(buffer);
}
@Override
public int available() throws IOException {
return inputStream.available();
}
@Override
public int read() throws IOException {
int data = inputStream.read();
if (data == -1) {
this.finished = true;
}
return data;
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
return inputStream.read(b, off, len);
}
@Override
public boolean isFinished() {
return this.finished;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {
throw new UnsupportedOperationException();
}
}
构建可重复读取inputStream的request
public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper {
private byte[] buffer;
public RepeatedlyRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
InputStream is = request.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buff[] = new byte[ 1024 ];
int read;
while( ( read = is.read( buff ) ) > 0 ) {
baos.write( buff, 0, read );
}
this.buffer = baos.toByteArray();
}
@Override
public ServletInputStream getInputStream() throws IOException {
return new BufferedServletInputStream( this.buffer );
}
}
拦截处的业务代码
request = new RepeatedlyRequestWrapper(request);
//业务代码
filterChain.doFilter(request, response);
这样过滤器拦截读取流之后,controller可以继续读取流数据了