DOIFOR技术基于Netty的HTTP服务实现
DOIFOR技术基于Netty的HTTP服务实现

基于Netty的HTTP服务实现

技术

之前写了一篇《IDEA插件开发之快速启动HTTP服务》提到了两种嵌入式HTTP服务的实现,后来想着既然是Java网络编程,那肯定是少不了大名鼎鼎的Netty。于是想着基于Netty以最小的代价实现一个http服务器。

file

netty官方带有一些常用的协议编码器,http就在其中,如果是编写服务器,则需要使用到HttpRequestDecoder 和HttpResponseEncoder,有一个HttpServerCodec类直接封装了这两个类。咱们还需要自行实现一个业务处理器,在这里先命名为HttpServerHandler吧。

然后直接上源码:

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.*;

import java.nio.charset.StandardCharsets;

public class HttpServer {
    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup bossGroup = new NioEventLoopGroup(5);
        EventLoopGroup workerGroup = new NioEventLoopGroup(20);
        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        socketChannel.pipeline()
                                .addLast(new HttpServerCodec())
                                .addLast(new HttpServerHandler());
                    }
                })
                .option(ChannelOption.SO_BACKLOG, 128)
                .childOption(ChannelOption.SO_KEEPALIVE, true);
        try {
            ChannelFuture channelFuture = bootstrap.bind(13388).sync();
            channelFuture.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

    private static class HttpServerHandler extends ChannelInboundHandlerAdapter {
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            if (msg instanceof HttpRequest request) {
                if ("/hello".equals(request.uri()) && request.method() == HttpMethod.GET) {
                    ByteBuf content = Unpooled.copiedBuffer("hello world".getBytes(StandardCharsets.UTF_8));
                    HttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content);
                    response.headers().set(HttpHeaderNames.CONTENT_TYPE,"text/html;charset=UTF-8") ;
                    response.headers().set(HttpHeaderNames.CONTENT_LENGTH,String.valueOf(content.readableBytes()));
                    ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE) ;
                }
            }
        }

    }
}

直接启动后在浏览器中访问 http://localhost:13388/hello 则可看到一下内容:
file

这里还有另一个问题,就是https不是默认支持的,如果需要支持https,需要将对应的编码器添加到处理流水线中去。

可参见:netty 实现https服务器

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注