本demo是学习netty,开发的第一个简单httpserver。
1.HttpServer主类(启动类)
package com.lzc.neety2;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
/**
* @author:luzaichun
* @Date:2021/5/4
* @Time:0:19
**/
public class HttpServer {
public static void main(String[] args) {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap
.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new MyChannelInitializer());
//绑定端口8888,启动netty的HttpServer
ChannelFuture channelFuture = serverBootstrap.bind(8888).sync();
System.out.println("服务器启动完成。。。。。。。。。。。。");
channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
- MyChannelInitializer继承自ChannelInitializer
自定义一个MyChannelInitializer主要是为了将主类中serverBootstrap.childHandler()这一坨代码提出来。方便后其维护
package com.lzc.neety2;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpServerCodec;
/**
* @author:luzaichun
* @Date:2021/5/4
* @Time:0:21
**/
public class MyChannelInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
//向管道中加入处理器
ChannelPipeline pipeline = socketChannel.pipeline();
pipeline
//加入一个netty提供的http的编码,解码处理器
.addLast(new HttpServerCodec())
//加入一个自定义的处理器
.addLast(new MyHttpServerHandler());
}
}
- 自定义的处理器
请求的接收何处理
package com.lzc.neety2;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;
import java.net.URI;
/**
* @author:luzaichun
* @Date:2021/5/4
* @Time:0:29 自定义的处理器
* SimpleChannelInboundHandler:是ChannelInboundHandlerAdapter子类
* HttpObject:客户端和服务器端相互通信的数据,被封装成HttpObject
**/
public class MyHttpServerHandler extends SimpleChannelInboundHandler<HttpObject> {
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, HttpObject httpObject) throws Exception {
if (httpObject instanceof HttpRequest) {
//拿到浏览器请求
HttpRequest httpRequest = (HttpRequest) httpObject;
//拿到请求的url和请求参数
URI uri = new URI(httpRequest.getUri());
String path = uri.getPath();
String query = uri.getQuery();
//过滤掉图标的请求
if ("/favicon.ico".equals(path)) {
return;
}
System.out.println("url:" + path);
System.out.println("paramters:" + query);
//TODO 拿到请求url和参数之后,就可以做route了
//回复消息
ByteBuf byteBuf = Unpooled.copiedBuffer("我是httpServer", CharsetUtil.UTF_8);
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, byteBuf);
response.headers().set(HttpHeaders.Names.CONTENT_TYPE, "text/plain;charset=utf-8");
response.headers().set(HttpHeaders.Names.CONTENT_LENGTH, byteBuf.readableBytes());
channelHandlerContext.writeAndFlush(response);
System.out.println("===========================服务器发送消息完毕========================");
}
}
}