Netty4:一个简单的web http的demo(简单的响应)

1.声明

当前内容主要为本人学习netty,用来记录学习过程和问题
主要内容为:实现一个简单的访问响应的http服务器!

  1. 主要采用netty内置的HttpRequestDecoder和HttpResponseEncoder来实现加码和解码
  2. 采用自定义的NettyHttpServerHandler来实现响应的写出

2.demo

1.服务器类:NettyHttpServer


/**
 * 
 * @author hy
 * @createTime 2021-04-24 10:05:25
 * @description 一个典型的netty的http服务器
 *
 */
public class NettyHttpServer implements Startable {
	private final int port;
	private final EventLoopGroup parentGroup;
	private final EventLoopGroup childGroup;
	private final ServerBootstrap serverBootstrap;

	public NettyHttpServer(int port) {
		this.port = port;
		this.parentGroup = new NioEventLoopGroup();
		this.childGroup = new NioEventLoopGroup();
		serverBootstrap = new ServerBootstrap();
	}

	@Override
	public void start() throws InterruptedException {
		try {
			serverBootstrap.option(ChannelOption.SO_BACKLOG, 1024);
			serverBootstrap
			.group(parentGroup, childGroup)
			.channel(NioServerSocketChannel.class)
			.childHandler(new NettyHttpServerChannelInitializer());
			
			Channel ch = serverBootstrap.bind(port).sync().channel();
			System.out.println("当前服务器启动在:http://localhost:" + port+"/");
			ch.closeFuture().sync();
		}finally {
			parentGroup.shutdownGracefully();
			childGroup.shutdownGracefully();
		}
		

	}

}

2.初始化当前的pipeline的类

/**
 * 
 * @author hy
 * @createTime 2021-04-24 10:03:57
 * @description 当前的netty http服务器的Channel初始化操作
 *
 */
public class NettyHttpServerChannelInitializer
		extends/* ChannelInitializer<SocketChannel> */ ChannelInitializer<Channel> {

	@Override
	protected void initChannel(Channel ch) throws Exception {
		// TODO Auto-generated method stub
		ch.pipeline()
				/* .addLast(new HttpServerCodec()) */
				/* .addLast(new HttpServerExpectContinueHandler()) */
		.addLast(new HttpRequestDecoder())  // 客户端传递数据解码
		.addLast(new NettyHttpServerHandler())
		.addLast(new HttpResponseEncoder()) ;// 响应客户端数据加码

	}

}

3.实际处理响应类

/**
 * 
 * @author hy
 * @createTime 2021-04-24 10:21:33
 * @description 一个服务器端的http处理器
 *
 */
public class NettyHttpServerHandler extends ChannelInboundHandlerAdapter {

	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("连接上了客户端!");
	}

	byte[] content = "{\"msg\":\"你好netty世界!\"}".getBytes(CharsetUtil.UTF_8);
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		// TODO Auto-generated method stub
		System.out.println(msg);

		// 每次接受到都直接响应..
		
		if (msg instanceof HttpRequest) {
			HttpRequest req = (HttpRequest) msg;

			boolean keepAlive = HttpUtil.isKeepAlive(req);
			FullHttpResponse response = new DefaultFullHttpResponse(req.protocolVersion(), HttpResponseStatus.OK,
					Unpooled.wrappedBuffer(content));

			response.headers()
			// 设置当前的响应头content-type =application/json;charset=utf-8
			.set(HttpHeaderNames.CONTENT_TYPE, "application/json;charset=utf-8")
			// 设置当前的响应头部content-length
			.setInt(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
			 ctx.channel().writeAndFlush(response);
		}
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		System.out.println("出现异常.............");
		cause.printStackTrace();
	}

}

3.基本测试

在这里插入图片描述
在这里插入图片描述

响应成功!

4.其中出现的问题

1.浏览器一直转动,但是没有响应数据:就是必须调用ctx.channel().writeAndFlush(response);,不要调用write方法

2.传递响应内容数据必须使用:DefaultFullHttpResponse这个类,并且必须在创建的时候指定数据(ByteBuf类型,使用Unpooled.wrappedBuffer(content)将字节转换为ByteBuf

5.总结

1.通过编写一个netty版的http服务器,很容易,并且也有很多坑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值