netty implements HTTP server 1

Keywords: Programming Netty Spring Java

Article directory

Summary

At present, the mainstream Java web server is implemented by springboot+Tomcat, and the bottom layer is developed based on servlet. Servlet is not asynchronous, so its performance is not very rational and cannot meet the requirements of the current fast server.

At present, spring 5 has realized asynchronous programming (responsive programming) based on reactor, and spring boot 2. X has also supported webplus, so the performance will be improved a lot. The underlying implementation is netty.

To learn more about reactive programming, go to my blog: Java 9 responsive programming support , which includes what is reactive programming, reactor's basic explanation and using reactive programming in spring boot.

Therefore, netty can not only be used as component communication, but also as HTTP server. Next, let's see how to use netty to implement HTTP server.

In this paper, we just use netty to build HTTP server. The function is not perfect enough and it can not be used for production service.

HTTP server code implementation

Write an HTTP server service class.

public class MyHttpServer {
    int port ;
    public MyHttpServer(int port){
        this.port = port;
    }

    public void start() throws Exception{
        ServerBootstrap bootstrap = new ServerBootstrap();
        EventLoopGroup boss = new NioEventLoopGroup();
        EventLoopGroup work = new NioEventLoopGroup();
        bootstrap.group(boss,work)
                .handler(new LoggingHandler(LogLevel.DEBUG))
                .channel(NioServerSocketChannel.class)
                .childHandler(new HttpServerInitializer());

        ChannelFuture f = bootstrap.bind(new InetSocketAddress(port)).sync();
        System.out.println("http server started . port : " + port);
        f.channel().closeFuture().sync();
    }

    public static void main(String[] args) throws Exception{
        MyHttpServer server = new MyHttpServer(8080);// 8080 is the start port
        server.start();
    }
}

class HttpServerInitializer extends ChannelInitializer<SocketChannel> {

    @Override
    protected void initChannel(SocketChannel channel) throws Exception {
        ChannelPipeline pipeline = channel.pipeline();
        pipeline.addLast(new HttpServerCodec());// http codec
        pipeline.addLast("httpAggregator",new HttpObjectAggregator(512*1024)); // http message aggregator 512 * 1024 is the maximum content length received
        pipeline.addLast(new HttpRequestHandler());// Request processor

    }
}

The above code mainly looks at the HttpServerInitializer class.
In my channel pipeline, HttpServerCodec, HttpObjectAggregator and HttpRequestHandler are added successively.

  • HttpServerCodec is the codec for HTTP messages. HttpServerCodec is a composite class of HttpRequestDecoder and HttpResponseEncoder, which is used to simplify HTTP programming.
  1. HttpRequestDecoder decodes ByteBuf to HttpRequest and HttpContent.
  2. HttpResponseEncoder is to encode HttpResponse or HttpContent to ByteBuf.
  • HttpObjectAggregator is used to aggregate HTTP messages, transforming multiple messages into a single FullHttpRequest and FullHttpResponse. Because the HttpServerCodec decoder produces multiple objects in each HTTP message: HttpRequest, HttpResponse, HttpContent, LastHttpContent.
  • HttpRequestHandler is our business logic processing class.

Request processing class HttpRequestHandler:

class HttpRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) {
        // Get the requested uri
        String uri = req.uri();
        Map<String,String> resMap = new HashMap<>();
        resMap.put("method",req.method().name());
        resMap.put("uri",uri);
        String msg = "<html><head><title>test</title></head><body>Your request uri For:" + uri+"</body></html>";
        // Create http response
        FullHttpResponse response = new DefaultFullHttpResponse(
                HttpVersion.HTTP_1_1,
                HttpResponseStatus.OK,
                Unpooled.copiedBuffer(msg, CharsetUtil.UTF_8));
        // Set header information
        response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html; charset=UTF-8");
        //response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8");
        // Write HTML to client
        ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
    }
}

Simply, it reads the request URL and replies to the client with a string.

Verification

Startup service

The browser accesses any string of localhost:8080 /. For example: http://localhost:8080/index1/q

In the browser page, return to:

Your request uri is: / index1/q
225 original articles published, 210 praised, 900000 visitors+
His message board follow

Posted by weezil on Sun, 09 Feb 2020 23:40:36 -0800