Bootstrap

Netty实现http请求

Netty学习

一、引入的包

<dependency>
   <groupId>io.netty</groupId>
   <artifactId>netty-all</artifactId>
  <version>4.1.43.Final</version>
</dependency>

二、服务端实现

在实现httpServer的时候,关键一步是添加HttpServerCodec处理器。这个是有netty为我们提供的Http处理器。

HttpServer 

public class HttpServer {

    public static void main(String[] args) {
        EventLoopGroup boss = new NioEventLoopGroup();
        EventLoopGroup worker = new NioEventLoopGroup();
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        try {
            serverBootstrap.group(boss, worker);
            serverBootstrap.channel(NioServerSocketChannel.class);
            serverBootstrap.childHandler(new ChannelInitializer<NioSocketChannel>() {
                @Override
                protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                    ChannelPipeline pipeline = nioSocketChannel.pipeline();
                    // 添加一个Netty提供的HTTP处理器
                    pipeline.addLast(new HttpServerCodec());
                    pipeline.addLast(new HttpServerHandler());

                    //pipeline.addLast(new HttpServerHandler0());

                    // 因为HttpServerCodec只能获取uri中参数,所以需要加上HttpObjectAggregator.
                    pipeline.addLast(new HttpObjectAggregator(65536));
                    pipeline.addLast(new HttpServerHandler1());
                }
            });
            serverBootstrap.bind("127.0.0.1",8888).sync();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

HttpServerHandler0,一个简单的http请求处理器。

public class HttpServerHandler0 extends SimpleChannelInboundHandler<HttpRequest> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, HttpRequest httpRequest) throws Exception {

        System.out.println("客户端的请求路径为:" + httpRequest.uri());

        // 创建一个响应对象,版本号与客户端保持一致
        DefaultFullHttpResponse response =
                new DefaultFullHttpResponse(httpRequest.protocolVersion(),
                        HttpResponseStatus.OK);
        // 构造响应内容
        byte[] content = "hello maomao".getBytes();

        // 告诉客户端本次响应的数据长度
        response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, content.length);
        response.content().writeBytes(content);
        ctx.writeAndFlush(response);
    }
}

HttpServerHandler1,可处理GET或者POST请求参数。需要注意的一点是,一定要加上pipeline.addLast(new HttpObjectAggregator(65536));  HttpObjectAggregator处理器,这个是用来设置参数大小的。

public class HttpServerHandler1 extends SimpleChannelInboundHandler<FullHttpRequest> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest httpRequest) throws Exception {
        System.out.println("客户端的请求路径为:" + httpRequest.uri());


        // 解析查询字符串
        QueryStringDecoder queryDecoder = new QueryStringDecoder(httpRequest.uri());
        Map<String, List<String>> queryParameters = queryDecoder.parameters();
        for (Map.Entry<String, List<String>> entry : queryParameters.entrySet()) {
            String key = entry.getKey();
            List<String> values = entry.getValue();
            System.out.println("Query Parameter: " + key + ", Values: " + values);
        }

        // 解析请求体
        ByteBuf contentBuf = httpRequest.content();
        String contentStr = contentBuf.toString(CharsetUtil.UTF_8);
        QueryStringDecoder bodyDecoder = new QueryStringDecoder(contentStr, false);
        Map<String, List<String>> bodyParameters = bodyDecoder.parameters();
        for (Map.Entry<String, List<String>> entry : bodyParameters.entrySet()) {
            String key = entry.getKey();
            List<String> values = entry.getValue();
            System.out.println("Body Parameter: " + key + ", Values: " + values);
        }

        // 创建一个响应对象,版本号与客户端保持一致,状态码为OK/200
        DefaultFullHttpResponse response =
                new DefaultFullHttpResponse(httpRequest.protocolVersion(),
                        HttpResponseStatus.OK);
        // 构造响应内容
        byte[] content = "hello maomao".getBytes();

        // 设置响应头:告诉客户端本次响应的数据长度
        response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, content.length);
        response.content().writeBytes(content);
        ctx.writeAndFlush(response);
    }

;