Netty構建HTTP服務

1. 眾所周知,Http協(xié)議的上層是TCP,Netty作為非阻塞框架的大佬,完全有能力承擔高并發(fā),高可用的角色.先上車,后解釋,
2. 可以用Netty創(chuàng)建一個TCP服務\color{red}{(測試Http的底層為TCP)},用瀏覽器請求,看能否收到請求,只要響應的是Http響應頭,瀏覽器就可以解析

1.HttpServer.java

public class HttpServer {
    public void start(int port) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .handler(new LoggingHandler(LogLevel.DEBUG))
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch)
                                throws Exception {
                            // server端發(fā)送的是httpResponse,所以要使用HttpResponseEncoder進行編碼
                            ch.pipeline().addLast(
                                    new HttpResponseEncoder());
                            // server端接收到的是httpRequest,所以要使用HttpRequestDecoder進行解碼
                            ch.pipeline().addLast(
                                    new HttpRequestDecoder());
                            ch.pipeline().addLast(
                                    new HttpObjectAggregator(512 * 1024));
                            ch.pipeline().addLast(
                                    new HttpServerHandler());
                            //增加自定義實現(xiàn)的Handler
                            ch.pipeline().addLast(new HttpServerCodec());
                        }
                    }).option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);
            ChannelFuture f = b.bind(port).sync();
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        HttpServer server = new HttpServer();
        server.start(8080);
    }
public class HttpServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        if (msg instanceof HttpRequest) {
            HttpRequest httpRequest = (HttpRequest) msg;
            System.out.println(Thread.currentThread().getId() + "->");
            System.out.println(httpRequest.uri() + ":" + ctx.channel().remoteAddress().toString());
            String uri = httpRequest.uri();
            if (msg instanceof HttpContent) {
                if(HttpPostRequestDecoder.isMultipart(httpRequest)){
                    // 是POST請求
                    HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(httpRequest);
                    decoder.offer((HttpContent)httpRequest);
                    List<InterfaceHttpData> parmList = decoder.getBodyHttpDatas();
                    System.out.println("form conent : \r\n" + parmList);
                }else{
                    HttpContent content = (HttpContent) msg;
                    ByteBuf buf = content.content();;
                    String requestString = buf.toString(io.netty.util.CharsetUtil.UTF_8);
                    buf.release();
                    System.out.println("json conent : \r\n" + requestString);
                }


            }
            Map<String, String> resMap = new HashMap<>();
            resMap.put("method", httpRequest.method().name());
            Set<Cookie> cookies = ServerCookieDecoder.LAX.decode(httpRequest.headers().get(HttpHeaderNames.COOKIE));
            resMap.put("uri", uri);
            // String text = "<html><head><title>test</title></head><body>你請求 port:"+ctx.channel().remoteAddress().toString()+" uri為:" + uri + ":" + httpRequest.headers().get(HttpHeaderNames.COOKIE) + "</body></html>";
            String text = "<html><head><title>test</title></head><body>你請求 port:" + ctx.channel().remoteAddress().toString() + " uri為:" + uri + "</body></html>";
            // 創(chuàng)建http響應
            FullHttpResponse response = new DefaultFullHttpResponse(
                    HttpVersion.HTTP_1_1,
                    HttpResponseStatus.OK,
                    Unpooled.copiedBuffer(text, CharsetUtil.UTF_8));
            // 設置頭信息
            response.headers().set(HttpHeaderNames.SET_COOKIE, ServerCookieEncoder.STRICT.encode("JSESESSION", "1234"));
            response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html; charset=UTF-8");
            // 將html write到客戶端
            ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);

        }

    }


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

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        String text = "<html><head><title>test</title></head><body>你請求uri為:" + cause.toString() + "</body></html>";

        FullHttpResponse response = new DefaultFullHttpResponse(
                HttpVersion.HTTP_1_1,
                HttpResponseStatus.OK,
                Unpooled.copiedBuffer(text, CharsetUtil.UTF_8));
        // 設置頭信息
        response.headers().set(HttpHeaderNames.SET_COOKIE, ServerCookieEncoder.STRICT.encode("JSESESSION", "1234"));
        response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html; charset=UTF-8");
        // 將html write到客戶端
        ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
        ctx.close();
    }

線程組:

 EventLoopGroup bossGroup = new NioEventLoopGroup();//主線程
 EventLoopGroup workerGroup = new NioEventLoopGroup();// 工作線程

主線程用來接受tcp請求并分發(fā),工作線程用來處理請求
解碼器(解析tcp請求過來的數(shù)據(jù))
HttpRequestDecoder() 
HttpPostRequestDecoder.isMultipart(httpRequest)
用來區(qū)分是表單還是Json
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 并不是 每一輛公車 十分鐘 就會準點來一班 正如并不是 每一段愛情 一兩年 就會準點來一趟 但在間隔里耐心靜候 終...
    大囍Daisy閱讀 215評論 0 1
  • 年紀大了,熬夜熬不住了。
    噸噸農場主閱讀 93評論 0 0
  • 最近一周遇到兩件比較奇葩的事—微信好友被對方刪除。本來這事也挺正常,現(xiàn)在一言不合即分,一語投機即婚的事也不少,何況...
    你的氣質閱讀 752評論 0 1
  • 《匆匆》 作者:魏城 匆匆 是上班族腳步的節(jié)奏 匆匆 是車輪與鐵軌摩擦的聲音 匆匆 是燕翅掠過的光影 匆匆 是歲月...
    魏城閱讀 240評論 1 2
  • 作為一個父親, 那天在萬達影城我熱淚盈眶, (身邊的兒子似乎面無表情) 當時鋼鐵俠哄女兒入睡, 說我愛你寶貝, 她...
    A南星學生教育中心林老師閱讀 694評論 0 1

友情鏈接更多精彩內容