Netty剖析之Http服务案例

前言

前面我们讲了Netty的线程模型,还有一些Netty的特性,以及使用Netty编写过一个Tcp服务案例,本次呢,我们将结合前面所学的知识,来编写一个Http服务案例

Http服务案例

需求:使用Netty编写一个Http服务端,可以让浏览器正常访问,并且服务端可以返回信息给浏览器。

服务端代码基本与前面的TCP服务一致,只是在pipeline管道里额外加入了处理http的编码、解码器(HttpServerCodec),自定义的handler不在继承ChannelInboundHandlerAdapter,而是继承SimpleChannelInboundHandler,详见如下代码:

public class HttpServer {
    public static void main(String[] args) throws Exception{

        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {

            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup,workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            // 获取管道对象
                            ChannelPipeline pipeline = socketChannel.pipeline();
                            // 添加netty提供的处理http的编码、解码器
                            pipeline.addLast(new HttpServerCodec());
                            // 加入自定义的handler
                            pipeline.addLast(new HttpServerHandler());
                        }
                    });

            ChannelFuture channelFuture = serverBootstrap.bind(8899).sync();
            channelFuture.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}
public class HttpServerHandler extends SimpleChannelInboundHandler<HttpObject> {

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, HttpObject httpObject) throws Exception {
        // 判断是不是Http请求
        if(httpObject instanceof HttpRequest){

            // 得到http请求
            HttpRequest httpRequest = (HttpRequest) httpObject;
            // 请求地址信息
            URI uri = new URI(httpRequest.uri());
            System.out.println("request url :" + uri.getPath());

            ByteBuf content = Unpooled.copiedBuffer("hello client", CharsetUtil.UTF_8);
            // 创建http响应对象
            DefaultFullHttpResponse httpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content);
            // 设置响应头
            httpResponse.headers().set(HttpHeaderNames.CONTENT_TYPE,"text/plan");
            httpResponse.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes());

            channelHandlerContext.writeAndFlush(httpResponse);
        }
    }
}

浏览器访问测试:
在这里插入图片描述
可以看到,浏览器请求成功了,并且收到了服务端响应的信息。

发布了107 篇原创文章 · 获赞 19 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/chen_changying/article/details/104154745