Netty 实现 Http 案例
HttpServer
java
public class HttpServer {
public static void main(String[] args) throws Exception{
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup,workerGroup)
.channel(NioServerSocketChannel.class)
//这里单独抽成了独立类 ServerInitializer
.childHandler(new ServerInitializer());//作用于 workerGroup
// 作用于 bossGroup
//.handler(new ChannelInitializer<SocketChannel>() {})
//监听 7778 端口
ChannelFuture future = bootstrap.bind(7778).sync();
future.channel().closeFuture().sync();
}finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
HttpServerHandler
java
public class HttpServerHandler extends SimpleChannelInboundHandler<HttpObject> {
// 读取客户端数据
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
if (msg instanceof HttpRequest httpRequest) {
//通过 uri 过滤特定资源
URI uri = new URI(httpRequest.uri());
if ("/favicon.ico".equals(uri.getPath())) {
System.out.println("请求了 favicon.ico, 不需要返回");
return;
}
// Unpooled 类是 Netty 提供的一个专门用于操作缓冲区的类
ByteBuf content = Unpooled.copiedBuffer("hello,我是服务器",
CharsetUtil.UTF_8);
FullHttpResponse response = new DefaultFullHttpResponse(
HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content);
//响应头信息设置
response.headers().set(HttpHeaderNames.CONTENT_TYPE,
"text/plain;charset=utf-8");
response.headers().set(HttpHeaderNames.CONTENT_LENGTH,
content.readableBytes());
ctx.writeAndFlush(response);
}
}
}
ServerInitializer
java
public class ServerInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
//向管道加入处理器
socketChannel.pipeline()
//编码处理器
.addLast("MyHttpServerCodec", new HttpServerCodec())
//自定义的 Http 响应处理器
.addLast("MyHttpServerHandler",new HttpServerHandler());
}
}
一个 Channel
包含了一个 ChannelPipeline
,ChannelPipeline
中维护了一个由 ChannelHandlerContext
组成的双向链表
- 入站事件会从链表
head
往后传递到最后一个入站的handler
- 出站事件从
tail
往前传递到第一个出站handler
- 浏览器访问,发现成功响应