netty處理http文件上傳

導入 netty-all-4.1.45.Final.jar 包

實現一個FileUploadRequestHandler類,繼承自SimpleChannelInboundHandler<FullHttpRequest>

    public static class FileUploadRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

        @Override
        protected void channelRead0(ChannelHandlerContext channelHandlerContext, FullHttpRequest fullHttpRequest) throws Exception {
            HttpDataFactory factory = new DefaultHttpDataFactory(true);
            HttpPostRequestDecoder httpDecoder = new HttpPostRequestDecoder(factory, fullHttpRequest);
            httpDecoder.setDiscardThreshold(0);
            final HttpContent chunk = fullHttpRequest;
            httpDecoder.offer(chunk);
            if (chunk instanceof LastHttpContent) {
                List<InterfaceHttpData> interfaceHttpDataList = httpDecoder.getBodyHttpDatas();
                for (InterfaceHttpData data : interfaceHttpDataList) {
                    if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.FileUpload) {
                        FileUpload fileUpload = (FileUpload) data;
                        try( FileOutputStream fileOutputStream = new FileOutputStream("netty_pic.png") ) {
                            fileOutputStream.write(fileUpload.get());
                            fileOutputStream.flush();
                        }
                    }
                    //如果數據類型爲參數類型,則保存到body對象中
                    if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute){
                        Attribute attribute = (Attribute) data;
                        System.out.println(attribute.getName() + ":" + attribute.getValue());
                    }
                }
            }

            FullHttpResponse response = new DefaultFullHttpResponse(
                    io.netty.handler.codec.http.HttpVersion.HTTP_1_1,
                    HttpResponseStatus.OK,
                    Unpooled.copiedBuffer("hello world", CharsetUtil.UTF_8));
            response.headers().set("Content-Type", "text/plain");
            response.headers().set("Content-Length", response.content().readableBytes());

            channelHandlerContext.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
        }
    }

啓動服務器

EventLoopGroup boss = new NioEventLoopGroup(1);
EventLoopGroup worker = new NioEventLoopGroup(2);
ServerBootstrap serverBootstrap = new ServerBootstrap();

try {
    serverBootstrap
        .group(boss, worker)
        .channel(NioServerSocketChannel.class)
        .childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
                ch.pipeline().addLast( new HttpServerCodec());
                ch.pipeline().addLast(new HttpObjectAggregator(1024 * 1024));
                ch.pipeline().addLast(new HttpServerExpectContinueHandler());
                ch.pipeline().addLast(new HttpRequestHandler());
            }
        });

    ChannelFuture future = serverBootstrap.bind(8088).sync();
    future.channel().closeFuture().sync();
} finally {
    boss.shutdownGracefully();
    worker.shutdownGracefully();
}

注意

EventLoopGroup boss = new NioEventLoopGroup(1);
EventLoopGroup worker = new NioEventLoopGroup(2);

這是兩個線程池,第一處理網絡連接的建立,第二個處理網絡IO讀寫,使用時可以根據自己的需求調整,但是不建議將這兩個值設的很多,業務處理的線程池建議和網絡線程隔離開。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章