使用Netty实现HTTP请求
使用Netty编写服务端,使用浏览器模拟HTTP请求,访问服务端。服务端返回的数据在浏览器显示。
服务端代码
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
public class TestService {
public static void main(String[] args) throws InterruptedException {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
// 创建bootstrap启动服务器
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class).childHandler(new TestServiceInitializer());
// 绑定端口启动服务器
ChannelFuture channelFuture = bootstrap.bind(8181).sync();
channelFuture.channel().closeFuture().sync();
}finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
添加ChannelInitializer
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpServerCodec;
public class TestServiceInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
// 向管道加入处理器
// 得到管道
ChannelPipeline pipeline = socketChannel.pipeline();
// 加入一个netty提供的httpServerCoder编解码器
pipeline.addLast("myHttpServerCodec",new HttpServerCodec());
// 增加自定义处理器
pipeline.addLast("MyTestHttpServiceHandler",new TestHttpServiceHandler());
}
}
自定义处理器
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;
/**
* SimpleChannelInboundHandler 是 ChannelInboundHandlerAdapter
* 泛型内,HttpObject为返回的数据类型
*/
public class TestHttpServiceHandler extends SimpleChannelInboundHandler<HttpObject> {
// 读取客户端数据
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
if (msg instanceof HttpRequest) {
System.out.println("客户端地址"+ ctx.channel().remoteAddress());
// 回复HTTP请求
ByteBuf content = Unpooled.copiedBuffer("服务器发送数据", CharsetUtil.UTF_8);
// 构造一个http的响应,即httpResponse
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content);
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes());
// 将构建好的response发送出去
ctx.writeAndFlush(response);
}
}
}
结果
使用浏览器调用,在浏览器看到服务器的返回数据,服务端可以看到前后建立了两次连接。
通过F12可以看到,确实存在两次请求,一次是期望的请求,另一次是请求浏览器图标。
使用资源过滤完成请求的排除
HttpRequest request = (HttpRequest) msg;
URI uri = new URI(request.uri());
if ("/favicon.ico".equals(uri.getPath())){
// 过去处理
return;
}
版权声明:本文为GxDong_原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。