Netty学习
一、引入的包
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.43.Final</version>
</dependency>
二、服务端实现
在实现httpServer的时候,关键一步是添加HttpServerCodec处理器。这个是有netty为我们提供的Http处理器。
HttpServer
public class HttpServer {
public static void main(String[] args) {
EventLoopGroup boss = new NioEventLoopGroup();
EventLoopGroup worker = new NioEventLoopGroup();
ServerBootstrap serverBootstrap = new ServerBootstrap();
try {
serverBootstrap.group(boss, worker);
serverBootstrap.channel(NioServerSocketChannel.class);
serverBootstrap.childHandler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
ChannelPipeline pipeline = nioSocketChannel.pipeline();
// 添加一个Netty提供的HTTP处理器
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new HttpServerHandler());
//pipeline.addLast(new HttpServerHandler0());
// 因为HttpServerCodec只能获取uri中参数,所以需要加上HttpObjectAggregator.
pipeline.addLast(new HttpObjectAggregator(65536));
pipeline.addLast(new HttpServerHandler1());
}
});
serverBootstrap.bind("127.0.0.1",8888).sync();
} catch (Exception e) {
e.printStackTrace();
}
}
}
HttpServerHandler0,一个简单的http请求处理器。
public class HttpServerHandler0 extends SimpleChannelInboundHandler<HttpRequest> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpRequest httpRequest) throws Exception {
System.out.println("客户端的请求路径为:" + httpRequest.uri());
// 创建一个响应对象,版本号与客户端保持一致
DefaultFullHttpResponse response =
new DefaultFullHttpResponse(httpRequest.protocolVersion(),
HttpResponseStatus.OK);
// 构造响应内容
byte[] content = "hello maomao".getBytes();
// 告诉客户端本次响应的数据长度
response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, content.length);
response.content().writeBytes(content);
ctx.writeAndFlush(response);
}
}
HttpServerHandler1,可处理GET或者POST请求参数。需要注意的一点是,一定要加上pipeline.addLast(new HttpObjectAggregator(65536)); HttpObjectAggregator处理器,这个是用来设置参数大小的。
public class HttpServerHandler1 extends SimpleChannelInboundHandler<FullHttpRequest> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest httpRequest) throws Exception {
System.out.println("客户端的请求路径为:" + httpRequest.uri());
// 解析查询字符串
QueryStringDecoder queryDecoder = new QueryStringDecoder(httpRequest.uri());
Map<String, List<String>> queryParameters = queryDecoder.parameters();
for (Map.Entry<String, List<String>> entry : queryParameters.entrySet()) {
String key = entry.getKey();
List<String> values = entry.getValue();
System.out.println("Query Parameter: " + key + ", Values: " + values);
}
// 解析请求体
ByteBuf contentBuf = httpRequest.content();
String contentStr = contentBuf.toString(CharsetUtil.UTF_8);
QueryStringDecoder bodyDecoder = new QueryStringDecoder(contentStr, false);
Map<String, List<String>> bodyParameters = bodyDecoder.parameters();
for (Map.Entry<String, List<String>> entry : bodyParameters.entrySet()) {
String key = entry.getKey();
List<String> values = entry.getValue();
System.out.println("Body Parameter: " + key + ", Values: " + values);
}
// 创建一个响应对象,版本号与客户端保持一致,状态码为OK/200
DefaultFullHttpResponse response =
new DefaultFullHttpResponse(httpRequest.protocolVersion(),
HttpResponseStatus.OK);
// 构造响应内容
byte[] content = "hello maomao".getBytes();
// 设置响应头:告诉客户端本次响应的数据长度
response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, content.length);
response.content().writeBytes(content);
ctx.writeAndFlush(response);
}