Netty4系列--实现简单的Http协议

     利用netty4来实现http的服务器,代码如下:

public class ApiServer {
    
    
   public static void main(String[] args) {
       int port = 8089;  
       if (args != null && args.length > 0) {  
           try {  
               port = Integer.parseInt(args[0]);  
           } catch (Exception e) {  
 
           }  
       }  
       try {
	new ApiServer().bind(port);
	System.out.println(String.format("start %s", port));
    } catch (Exception e) {
	// TODO Auto-generated catch block
	System.out.println(e.getMessage());
    }  
}
   
   public void bind(int port) throws Exception {  
       NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);
	NioEventLoopGroup workerGroup = new NioEventLoopGroup();
	try {
	    ServerBootstrap boot = new ServerBootstrap();
	    boot.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<Channel>() {
		@Override
		protected void initChannel(Channel ch) throws Exception {
		    // server端是接收  ,所以这里是httprequest解码
		    ch.pipeline().addLast(new HttpRequestDecoder());
		    // 消息合并+最大2M,防止半包问题
		    ch.pipeline().addLast("http-aggregator", new HttpObjectAggregator(2 * 1024 * 1024));
		    //server端会返回respose 所以这里是进行编码
		    ch.pipeline().addLast(new HttpResponseEncoder());
		    //处理器
		    ch.pipeline().addLast(new HttpMessageHandler());
		}
	    });
	  //绑定端口,同步等待成功  
            ChannelFuture f = boot.bind(port).sync();  
            System.out.println("yes bind"+port);
            //等待服务端监听端口关闭;  
            f.channel().closeFuture().sync();  
	}
	catch (Exception e) {
	    System.out.println(e.getMessage());
	}finally {
	    bossGroup.shutdownGracefully();
	    workerGroup.shutdownGracefully();
	}
   }

}

    由于这里是实现server端的,所以对于接收的请求需要进行解码,另外在进行接收消息的时候为了避免半包的问题需要使用了读取消息的长度。最后这里会进行输出的响应,因此这里是使用了ReponseEncode。

     在netty 4中,实现消息的处理是继承ChannelInboundHandlerAdapter 类,代码如下:

    

public class HttpMessageHandler extends ChannelInboundHandlerAdapter {
    
    private static Log  LOG=LogFactory.getLog(HttpMessageHandler.class);
  
     //进行消息的接收
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
	//在这里进行读取内容
	if(msg instanceof HttpRequest){
	    HttpRequest request=(HttpRequest)msg;
	    String url =request.uri();
	    //判断方法
	    Map<String, String> paramMap=new HashMap<String,String>();
	    if(request.method().name().equals(HttpMethod.GET.name())){
		//get 请求
		//获取参数
		QueryStringDecoder     parmDecoder= new QueryStringDecoder(url);
		
		Map<String,List<String>>  params=parmDecoder.parameters();
		if(!params.isEmpty()){
	                params.forEach((k,v)->{
	                    v.forEach(item->{
	                	paramMap.put(k, item);
	                	System.out.println(String.format("get %s:%s", k,item));
	                    });
	                });
		}
		 String res = "I am OK";
	         write(ctx, res, null);
		
		//获取get的参数
		
	    }else if(request.method().name().equals(HttpMethod.POST.name())){
		//post 请求
		HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(request);
	            decoder.offer((HttpContent)request);

	            List<InterfaceHttpData> parmList = decoder.getBodyHttpDatas();

	            for (InterfaceHttpData parm : parmList) {

	                Attribute data = (Attribute) parm;
	                paramMap.put(data.getName(), data.getValue());
	                System.out.println(String.format("post %s_%s", data.getName(),data.getValue()));
	            }
	            String res = "I am OK";
	            write(ctx, res, null);
	    }
	}else{
	    //进行返回404
	    String res = "404";
            write(ctx, res, null);
	}
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
	super.exceptionCaught(ctx, cause);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
	super.channelReadComplete(ctx);
    }
    //写入,发送回客户端
    private  void write(ChannelHandlerContext ctx,String res,String contentType) {
	
	byte[] bytes=null;
		try {
		    bytes=res.getBytes("UTF-8");
		} catch (UnsupportedEncodingException e) {
		    // TODO Auto-generated catch block
		    e.printStackTrace();
		}
	FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
    	    HttpResponseStatus.OK, Unpooled.wrappedBuffer(bytes));
	if(contentType!=null){
	    response.headers().set(HttpHeaders.Names.CONTENT_TYPE, "text/plain");
	}else{
	    response.headers().set(HttpHeaders.Names.CONTENT_TYPE, "text/plain");
	}
        response.headers().set(HttpHeaders.Names.CONTENT_LENGTH,
                response.content().readableBytes());
        ctx.write(response);
        ctx.flush();
    }
}
    在这里通过去判断request的方法类型来去获取参数,最后是通过FullHttpResponse来进行响应头的输出。

         


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值