首先,需要了解Nio vs Io。需要了解如何通过Nio进行读取
Nio读取
public class App
{
public static void main( String[] args )
{
// 到buffer
ByteBuffer byteBuffer = MappedByteBuffer.wrap("reader.read()".getBytes());
// 转换读取模式
byteBuffer.flip();
// 打标记
byteBuffer.mark();
byte[] buffer = new byte[1024];
try{
// 读取buffer
while (byteBuffer.hasRemaining()){
int remaining = byteBuffer.remaining();
int length = Math.min(remaining, buffer.length);
if (remaining > 0){
byteBuffer.get(buffer);
}
// writer.write(buffer,length);
}
}catch (Exception e){
byteBuffer.reset();
}
// 刷新
// write.flush()
}
}
案例实操
在SpingBoot中添加一个拦截器进行请求的读取,让在Controller返回请求的内容。
拦截器(读取请求打印日志)
@Component
public class TestInterceptor implements HandlerInterceptor {
Logger logger = LoggerFactory.getLogger(TestInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
int contentLength = request.getContentLength();
BufferedReader reader = request.getReader();
char[] buffer = new char[contentLength];
// 打个标记
reader.mark(contentLength);
reader.read(buffer);
// 重置标记
reader.reset();
logger.info("interceptor content:{}", new String(buffer));
return true;
}
}
Controller读取并返回请求
@RestController
public class TestController {
Logger logger = LoggerFactory.getLogger(TestController.class);
@GetMapping(value = "/go")
public void read(HttpServletRequest request, HttpServletResponse response) throws Exception {
int contentLength = request.getContentLength();
BufferedReader reader = request.getReader();
char[] buffer = new char[contentLength];
// 打个标记
reader.mark(contentLength);
reader.read(buffer);
// 重置buffer
reader.reset();
logger.info("controller content:{}", new String(buffer));
buffer = new char[contentLength];
reader.read(buffer);
response.getWriter().write(buffer, 0, contentLength);
}
}
总结
通过使用Nio读取请求内容可以实现重复读取请求。