Netty 是一個基於 JAVA NIO 類庫的異步通訊框架,它的架構特色是:異步非阻塞、基於事件驅動、高性能、高可靠性和高可定製性。換句話說,Netty是一個NIO框架,使用它能夠簡單快速地開發網絡應用程序,好比客戶端和服務端的協議。Netty大大簡化了網絡程序的開發過程好比TCP和UDP的 Socket的開發。Netty 已逐漸成爲 Java NIO 編程的首選框架,Netty中,通信的雙方創建鏈接後,會把數據按照ByteBuf的方式進行傳輸,所以咱們在構建Http服務器的時候就是經過HttpRequestDecoder對ByteBuf數據流進行處理,轉換成http的對象。代碼以下:html
maven依賴java
<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.0.Final</version> </dependency>
HttpServer類編程
package com.example.demo.netty; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.EventLoopGroup; 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.HttpServerCodec; public class HttpServer { public static void main(String[] args) throws InterruptedException { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new HttpServerCodec()); pipeline.addLast(new HttpServerHandler()); } }); ChannelFuture f = b.bind(8080).sync(); f.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } } }
HttpServerHandler類bootstrap
package com.example.demo.netty; import java.io.UnsupportedEncodingException; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpVersion; import io.netty.handler.codec.http.QueryStringDecoder; class HttpServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws UnsupportedEncodingException { if (msg instanceof HttpRequest) { // 請求,解碼器將請求轉換成HttpRequest對象 HttpRequest request = (HttpRequest) msg; // 獲取請求參數 QueryStringDecoder queryStringDecoder = new QueryStringDecoder(request.uri()); String name = "netty"; if(queryStringDecoder.parameters().get("name") != null) { name = queryStringDecoder.parameters().get("name").get(0); } // 響應HTML String responseHtml = "<html><body>Hello, " + name + "</body></html>"; byte[] responseBytes = responseHtml.getBytes("UTF-8"); int contentLength = responseBytes.length; // 構造FullHttpResponse對象,FullHttpResponse包含message body FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer(responseBytes)); response.headers().set("Content-Type", "text/html; charset=utf-8"); response.headers().set("Content-Length", Integer.toString(contentLength)); ctx.writeAndFlush(response); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); } }
運行HttpServer中main方法,啓動httpServer,打開瀏覽器輸入http://localhost:8080?name=zhangsan ,結果以下:瀏覽器