用Netty实现Http服务器

需求点

  1. 实现Get,Post功能
  2. 打印Http请求方法,请求地址,Body内容
  3. 返回数据到前端 。
看代码如下
HttpServer
public class HttpServer {public void run(int port){EventLoopGroup bossGroup = new NioEventLoopGroup();EventLoopGroup workGroup = new NioEventLoopGroup();ServerBootstrap bootstrap = new ServerBootstrap();bootstrap.group(bossGroup,workGroup).channel(NIOServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {//设置http解码器ch.pipeline().addLast(new HttpRequestDecoder());//设置http内容处理器ch.pipeline().addLast(new HttpObjectAggregator(65536));//设置http编码器ch.pipeline().addLast(new HttpResponseEncoder());//自定义服务处理器ch.pipeline().addLast(new HttpServerHandler());}});try {ChannelFuture future = bootstrap.bind(8080).sync();System.out.println("服务器启动成功");future.channel().closeFuture().sync();}catch (Exception e){e.printStackTrace();}finally {bossGroup.shutdownGracefully();workGroup.shutdownGracefully();}}public static void main(String[] args) {new HttpServer().run(8080);}}自定义网络I/O时间处理器HttpServerHandler
public class HttpServerHandler extends ChannelInboundHandlerAdapter {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {//判断是不是http请求if(msg instanceof HttpRequest){HttpRequest httpRequest = (HttpRequest) msg;parseUri(httpRequest);parseHttpMethod(httpRequest);parseHttpHeaders(httpRequest);parseBody(httpRequest);FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrAppedBuffer("ok".getBytes()));HttpUtil.setContentLength(res, res.content().readableBytes());ctx.writeAndFlush(res);}super.channelRead(ctx, msg);}/*** 获得请求方式* @param httpRequest*/private HttpMethod parseHttpMethod(HttpRequest httpRequest){HttpMethod httpMethod = httpRequest.method();System.out.println("method:"+httpMethod.name());return httpMethod;}/*** 打印头部信息* @param httpRequest*/private HttpHeaders parseHttpHeaders(HttpRequest httpRequest){HttpHeaders httpHeaders = httpRequest.headers();for (Map.Entry<String, String> entry : httpHeaders.entries()) {System.out.println(entry.getKey()+":"+entry.getValue());}return httpHeaders;}/*** 打印请求地址* @param httpRequest*/private void parseUri(HttpRequest httpRequest){String uri = httpRequest.uri();System.out.println("uri:"+uri);}/*** 打印请求体* @param httpRequest*/private void parseBody(HttpRequest httpRequest){if(httpRequest instanceof HttpContent){HttpContent httpContent = (HttpContent) httpRequest;System.out.println("content:"+httpContent.content().toString(Charset.defaultCharset()));}}}【用Netty实现Http服务器】启动HttpServer 。
网页输入http://localhost:8080/
控制台显示
uri:/method:GETHost:localhost:8080Connection:keep-aliveCache-Control:max-age=0Upgrade-Insecure-Requests:1User-Agent:Mozilla/5.0 (windows NT 6.1; Win64; x64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/85.0.4183.102 Safari/537.36Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Sec-Fetch-Site:noneSec-Fetch-Mode:navigateSec-Fetch-User:?1Sec-Fetch-Dest:documentAccept-Encoding:gzip, deflate, brAccept-Language:en,zh-CN;q=0.9,zh;q=0.8content-length:0content:PostMan用Post方式请求http://localhost:8080/
控制台显示如下
uri:/method:POSTContent-Type:text/plainUser-Agent:PostmanRuntime/7.26.3Accept:*/*Cache-Control:no-cachePostman-Token:dbdb420e-5403-40da-8d8f-e2c11029c390Host:localhost:8080Accept-Encoding:gzip, deflate, brConnection:keep-aliveContent-Length:21content:{"test":1212}代码实现起来不难,我们一步步来解析,为什么要这样做 。
 
HttpRequestDecoder
首先HttpRequestDecoder是一个解码器,那就是从网络读取字节流来处理 。
它的主要功能是,解析ByteBuf转化成Http请求的相关数据,例如将请求数据转化成,HttpRequest/HttpResponse,HttpContent,LastHttpContent 。
 
HttpObjectAggregator
HttpObjectAggregator的作用是聚合,因为HttpRequestDecoder会解析成多个Http相关对象,它将它们聚合成一个对象 。
HttpResponseEncoder
HttpResponseEncoder的作用是用来编码,将我们响应的Http对象,转化成ByteBuf,进行网络通信 。
 
我们最终需要把网络请求的数据转化成http请求的相关类 。
我这里用相关类来表示,不特指netty的httpRequest和HttpResponse 。因为我们自己也可以自定义实现 。只要按照http请求的报文做相应的解析即可 。


推荐阅读