Netty之http协议开发

本文介绍使用Netty进行HTTP开发的基本流程和技术要点,包括HTTP请求与响应的组成、Netty HTTP开发示例代码解析等。

Netty HTTP协议开发应用:

由于Netty的HTTP协议栈是基于Netty的NIO通信框架开发的,因此Netty的HTTP协议也是异步非阻塞的。

这里写图片描述
HTTP请求消息:
HTTP请求由三部分组成,具体如下:

  • HTTP请求行

请求行以一个方法符开头,以空格分开,后面跟着请求的URI和协议的版本,格式为:Method Request-URI HTTP-Version CRLF。
其中Method表示请求方法,Request-URI是一个统一资源标识符,HTTP-Version表示请求的HTTP协议版本,CRLF表示回车和换行。请求方法有多种,各方法的作用如下:
这里写图片描述

  • HTTP消息头

这里写图片描述

  • HTTP请求正文

HTTP 响应消息:
处理完HTTP客户端的请求之后,HTTP服务端返回响应消息给客户端,HTTP响应也是有三个部分组成。分别是:
- 状态行

状态行的格式为:HTTP-Version Status-Code Reason-Phrase CRLF。
Status-Code表示服务器返回的响应状态代码。状态代码由三位数字组成,第一个数字定义了响应的类别,他有五种可能取值:

这里写图片描述
这里写图片描述

  • 消息报头

  • 响应正文

Netty5 示例:


            System.out.println("HTTP 服务端启动,端口:"+port);
            EventLoopGroup bossGroup = new NioEventLoopGroup();
            EventLoopGroup workerGroup = new NioEventLoopGroup();
            try {
                ServerBootstrap b = new ServerBootstrap();
                b.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch)
                            throws Exception {
                        //HTTP 请求消息解码器
                        ch.pipeline().addLast("http-decoder",
                                new HttpRequestDecoder());
                        //HttpObjectAggregator解码器,将多个消息转换成单一的FullHttpRequest或者FullHTtpResponse,原因是HTTP解码器在每个HTTP消息中会生成多个消息对象(HttpRequst、HttpResponse、Httpontent/LastHttpContent)。
                        ch.pipeline().addLast("http-aggregator",
                                new HttpObjectAggregator(65536));
                        //HTTP响应结卖钱
                        ch.pipeline().addLast("http-encoder",
                                new HttpResponseEncoder());
                        //Chunked handler它的作用是支持异步发送大的码流但不占用过多的内存,防止发生java内存溢出错误。
                        ch.pipeline().addLast("http-chunked",
                                new ChunkedWriteHandler());
                        ch.pipeline().addLast("httpServerHandler",
                                new HttpReceiveHandler());
                    }
                });
                ChannelFuture future = b.bind( port).sync();
                future.channel().closeFuture().sync();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
            }
package com.bh.service;

import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpContent;
import io.netty.util.CharsetUtil;

import java.util.concurrent.atomic.AtomicInteger;

import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

import com.bh.client.SendClient;

/**
 * @author cyq
 *
 */
public class HttpReceiveHandler extends ChannelHandlerAdapter  {

    public static  AtomicInteger httpReceiveTotal=new AtomicInteger();

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        if (msg instanceof HttpContent) {
            HttpContent httpContent = (HttpContent) msg;
            ByteBuf content = httpContent.content();
            final StringBuilder buf = new StringBuilder();
            buf.append(content.toString(CharsetUtil.UTF_8));
            httpReceiveTotal.incrementAndGet();
            //转发
            String responseMessage="false";
            try {
                JSONObject jsonObj=new JSONObject(buf.toString());
                String sendType=jsonObj.getString("sendType");
                String sendUri= jsonObj.getString("url");
                String message= jsonObj.getString("message");
                responseMessage = SendClient.send(sendType, sendUri, message);
            } catch (JSONException e) {
                e.printStackTrace();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK);
            response.headers().set(CONTENT_TYPE, "text/html; charset=UTF-8");
            ByteBuf buffer = Unpooled.copiedBuffer(responseMessage, CharsetUtil.UTF_8);
            response.content().writeBytes(buffer);
            buffer.release();
            ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值