基于nio实现请求重复读取

89 阅读1分钟

首先,需要了解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读取请求内容可以实现重复读取请求。