服务器端代码
public class NettyServer {
public static void main(String[] args) {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup,workerGroup)
// .option(ChannelOption.SO_BACKLOG,128)
// .childOption(ChannelOption.SO_KEEPALIVE,true)
.channel(NioServerSocketChannel.class)
.childHandler(new NettyInit());
ChannelFuture channelFuture = serverBootstrap.bind(8080).sync();
channelFuture.channel().closeFuture().sync();
}catch (Exception e){
e.printStackTrace();
}finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
}
childHandler类
public class NettyInit extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel channel) throws Exception {
ChannelPipeline pipeline = channel.pipeline();
//HttpClientCodec是netty提供的编解码器
pipeline.addLast("httpCodec",new HttpServerCodec());
pipeline.addLast(new NettyHandler());
}
}
NettyHandler类
public class NettyHandler extends SimpleChannelInboundHandler<HttpObject> {
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, HttpObject httpObject) throws Exception {
if(httpObject instanceof HttpRequest){
System.out.println("类型:"+httpObject.getClass());
System.out.println(channelHandlerContext.channel().remoteAddress());
// 回复信息给浏览器
ByteBuf content = Unpooled.copiedBuffer("你好,浏览器", CharsetUtil.UTF_8);
// 构造http响应
DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content);
// 构造header
response.headers().set(HttpHeaderNames.CONTENT_TYPE,"text/plain");
response.headers().set(HttpHeaderNames.CONTENT_LENGTH,response.content().readableBytes());
// 返回
channelHandlerContext.writeAndFlush(response);
}
}
}
这个时候用360浏览器请求8080端口,响应信息。
但是你会发现,输出了两次信息
类型:class io.netty.handler.codec.http.DefaultHttpRequest
/0:0:0:0:0:0:0:1:63509
类型:class io.netty.handler.codec.http.DefaultHttpRequest
/0:0:0:0:0:0:0:1:63509
我们经过F12查看发现
过滤URI
请求图标也进行了除了,所以我们可以在NettyHandler中对URI做出处理
public class NettyHandler extends SimpleChannelInboundHandler<HttpObject> {
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, HttpObject httpObject) throws Exception {
if(httpObject instanceof HttpRequest){
// 加上判定,思路可以自己决定
HttpRequest msg = (HttpRequest)httpObject;
URI uri = new URI(msg.uri());
if(uri.getPath().equals("/favicon.ico")){
return;
}
System.out.println("类型:"+httpObject.getClass());
System.out.println(channelHandlerContext.channel().remoteAddress());
// 回复信息给浏览器
ByteBuf content = Unpooled.copiedBuffer("你好,浏览器", CharsetUtil.UTF_8);
// 构造http响应
DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content);
// 构造header
response.headers().set(HttpHeaderNames.CONTENT_TYPE,"text/plain");
response.headers().set(HttpHeaderNames.CONTENT_LENGTH,response.content().readableBytes());
// 返回
channelHandlerContext.writeAndFlush(response);
}
}
}
由于http协议用一次断一次,所以每次请求都会产生新的pipeline。
ServerBootstrap
ServerBootstrap的handler方法对应的是bossGroup,childHandler对应的是workerGroup。
设置channel时,不同的channel对应不同的类型