netty
自带 http
解码器。
new HttpServerCodec()
使用 new HttpServerCodec()
会将数据解析成两个
DefaultHttpRequest
HttpContent
该处理器既是出站处理器也是入站处理器。
所以,接收数据可以写成
服务端 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 package com.redisc;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInboundHandlerAdapter;import io.netty.channel.ChannelInitializer;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.DefaultHttpRequest;import io.netty.handler .codec.http.HttpContent;import io.netty.handler .codec.http.HttpServerCodec;import io.netty.handler .logging.LogLevel;import io.netty.handler .logging.LoggingHandler;import lombok.extern.slf4j.Slf4j;import java.io.IOException;@Slf 4jpublic class Server { public static void main (String[] args) throws IOException { NioEventLoopGroup boss = new NioEventLoopGroup(); NioEventLoopGroup worker = new NioEventLoopGroup(); try { ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.channel(NioServerSocketChannel.class ) ; serverBootstrap.group(boss, worker); serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel (SocketChannel socketChannel) throws Exception { socketChannel.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG)); socketChannel.pipeline().addLast(new HttpServerCodec()); socketChannel.pipeline().addLast(new ChannelInboundHandlerAdapter() { @Override public void channelRead (ChannelHandlerContext ctx, Object msg) throws Exception { if (msg instanceof DefaultHttpRequest) { } else if (msg instanceof HttpContent) { } } }); } }); ChannelFuture channelFuture = serverBootstrap.bind(8000 ).sync(); channelFuture.channel().closeFuture().sync(); } catch (InterruptedException e) { log.error ("error" , e); } finally { boss.shutdownGracefully(); worker.shutdownGracefully(); } } }
但是,每次我们用 if else
判断可能不优雅,比如,有时候,我们只需要请求体,所以可以简化成
直接在浏览器访问 http://127.0.0.1:8000/index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 package com.redisc;import io.netty.bootstrap.ServerBootstrap;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 io.netty.handler .logging.LogLevel;import io.netty.handler .logging.LoggingHandler;import lombok.extern.slf4j.Slf4j;import java.io.IOException;import static io.netty.handler .codec.http.HttpHeaderNames.CONTENT_LENGTH;@Slf 4jpublic class Server { public static void main (String[] args) throws IOException { NioEventLoopGroup boss = new NioEventLoopGroup(); NioEventLoopGroup worker = new NioEventLoopGroup(); try { ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.channel(NioServerSocketChannel.class ) ; serverBootstrap.group(boss, worker); serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel (SocketChannel socketChannel) throws Exception { socketChannel.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG)); socketChannel.pipeline().addLast(new HttpServerCodec()); socketChannel.pipeline().addLast(new SimpleChannelInboundHandler<HttpRequest>() { @Override protected void channelRead0 (ChannelHandlerContext channelHandlerContext, HttpRequest msg) throws Exception { DefaultFullHttpResponse defaultHttpResponse = new DefaultFullHttpResponse(msg.protocolVersion(), HttpResponseStatus.OK); byte [] b = "<h1>hello</h1>" .getBytes(); defaultHttpResponse.headers().setInt(CONTENT_LENGTH, b.length); defaultHttpResponse.content().writeBytes(b); channelHandlerContext.writeAndFlush(defaultHttpResponse); } }); } }); ChannelFuture channelFuture = serverBootstrap.bind(8000 ).sync(); channelFuture.channel().closeFuture().sync(); } catch (InterruptedException e) { log.error ("error" , e); } finally { boss.shutdownGracefully(); worker.shutdownGracefully(); } } }
通过使用简单处理器,SimpleChannelInboundHandler
中传递 HttpContent
里面就可以直接收 HttpContent
的内容了。