java netty httpreq_基于Netty4的HttpServer和HttpClient的简单实现

Netty的主页:http://netty.io/index.html

使用的Netty的版本:netty-4.0.23.Final.tar.bz2 ‐ 15-Aug-2014 (Stable, Recommended)

Http 消息格式:

Http request:

Method path-to-resource HTTPVersion-number

Header-name-1: value1

Header-name-2: value2

Optional request body

Http response:

HTTP/Version-number response-code response-phrase

Header-name-1: value1

Header-name-2: value2

Optional response body

实现一个简单的Http请求及响应过程:

1、Client向Server发送http请求。

2、Server端对http请求进行解析。

3、Server端向client发送http响应。

4、Client对http响应进行解析。

Netty中Http request消息格式:

c7682404c3b73f41af651e8ad2d6ea16.png

Netty中Http response消息格式:

2b915f9280ceb62e16b6e5df0778a2c6.png

代码实例:

Http Server:

packagecom.netty.test;importorg.apache.commons.logging.Log;importorg.apache.commons.logging.LogFactory;importio.netty.bootstrap.ServerBootstrap;importio.netty.channel.ChannelFuture;importio.netty.channel.ChannelInitializer;importio.netty.channel.ChannelOption;importio.netty.channel.EventLoopGroup;importio.netty.channel.nio.NioEventLoopGroup;importio.netty.channel.socket.SocketChannel;importio.netty.channel.socket.nio.NioServerSocketChannel;importio.netty.handler.codec.http.HttpRequestDecoder;importio.netty.handler.codec.http.HttpResponseEncoder;public classHttpServer {private static Log log = LogFactory.getLog(HttpServer.class);public void start(int port) throwsException {

EventLoopGroup bossGroup= newNioEventLoopGroup();

EventLoopGroup workerGroup= newNioEventLoopGroup();try{

ServerBootstrap b= newServerBootstrap();

b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)

.childHandler(new ChannelInitializer() {

@Overridepublic void initChannel(SocketChannel ch) throwsException {//server端发送的是httpResponse,所以要使用HttpResponseEncoder进行编码

ch.pipeline().addLast(newHttpResponseEncoder());//server端接收到的是httpRequest,所以要使用HttpRequestDecoder进行解码

ch.pipeline().addLast(newHttpRequestDecoder());

ch.pipeline().addLast(newHttpServerInboundHandler());

}

}).option(ChannelOption.SO_BACKLOG,128)

.childOption(ChannelOption.SO_KEEPALIVE,true);

ChannelFuture f=b.bind(port).sync();

f.channel().closeFuture().sync();

}finally{

workerGroup.shutdownGracefully();

bossGroup.shutdownGracefully();

}

}public static void main(String[] args) throwsException {

HttpServer server= newHttpServer();

log.info("Http Server listening on 8844 ...");

server.start(8844);

}

}

响应请求的HttpServerInboundHandler:

packagecom.netty.test;import staticio.netty.handler.codec.http.HttpHeaders.Names.CONNECTION;import staticio.netty.handler.codec.http.HttpHeaders.Names.CONTENT_LENGTH;import staticio.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;import staticio.netty.handler.codec.http.HttpResponseStatus.OK;import staticio.netty.handler.codec.http.HttpVersion.HTTP_1_1;importorg.apache.commons.logging.Log;importorg.apache.commons.logging.LogFactory;importio.netty.buffer.ByteBuf;importio.netty.buffer.Unpooled;importio.netty.channel.ChannelHandlerContext;importio.netty.channel.ChannelInboundHandlerAdapter;importio.netty.handler.codec.http.DefaultFullHttpResponse;importio.netty.handler.codec.http.FullHttpResponse;importio.netty.handler.codec.http.HttpContent;importio.netty.handler.codec.http.HttpHeaders;importio.netty.handler.codec.http.HttpHeaders.Values;importio.netty.handler.codec.http.HttpRequest;public class HttpServerInboundHandler extendsChannelInboundHandlerAdapter {private static Log log = LogFactory.getLog(HttpServerInboundHandler.class);privateHttpRequest request;

@Overridepublic voidchannelRead(ChannelHandlerContext ctx, Object msg)throwsException {if (msg instanceofHttpRequest) {

request=(HttpRequest) msg;

String uri=request.getUri();

System.out.println("Uri:" +uri);

}if (msg instanceofHttpContent) {

HttpContent content=(HttpContent) msg;

ByteBuf buf=content.content();

System.out.println(buf.toString(io.netty.util.CharsetUtil.UTF_8));

buf.release();

String res= "I am OK";

FullHttpResponse response= newDefaultFullHttpResponse(HTTP_1_1,

OK, Unpooled.wrappedBuffer(res.getBytes("UTF-8")));

response.headers().set(CONTENT_TYPE,"text/plain");

response.headers().set(CONTENT_LENGTH,

response.content().readableBytes());if(HttpHeaders.isKeepAlive(request)) {

response.headers().set(CONNECTION, Values.KEEP_ALIVE);

}

ctx.write(response);

ctx.flush();

}

}

@Overridepublic void channelReadComplete(ChannelHandlerContext ctx) throwsException {

ctx.flush();

}

@Overridepublic voidexceptionCaught(ChannelHandlerContext ctx, Throwable cause) {

log.error(cause.getMessage());

ctx.close();

}

}

Http Client:

packagecom.netty.test;importio.netty.bootstrap.Bootstrap;importio.netty.buffer.Unpooled;importio.netty.channel.ChannelFuture;importio.netty.channel.ChannelInitializer;importio.netty.channel.ChannelOption;importio.netty.channel.EventLoopGroup;importio.netty.channel.nio.NioEventLoopGroup;importio.netty.channel.socket.SocketChannel;importio.netty.channel.socket.nio.NioSocketChannel;importio.netty.handler.codec.http.DefaultFullHttpRequest;importio.netty.handler.codec.http.HttpHeaders;importio.netty.handler.codec.http.HttpMethod;importio.netty.handler.codec.http.HttpRequestEncoder;importio.netty.handler.codec.http.HttpResponseDecoder;importio.netty.handler.codec.http.HttpVersion;importjava.net.URI;public classHttpClient {public void connect(String host, int port) throwsException {

EventLoopGroup workerGroup= newNioEventLoopGroup();try{

Bootstrap b= newBootstrap();

b.group(workerGroup);

b.channel(NioSocketChannel.class);

b.option(ChannelOption.SO_KEEPALIVE,true);

b.handler(new ChannelInitializer() {

@Overridepublic void initChannel(SocketChannel ch) throwsException {//客户端接收到的是httpResponse响应,所以要使用HttpResponseDecoder进行解码

ch.pipeline().addLast(newHttpResponseDecoder());//客户端发送的是httprequest,所以要使用HttpRequestEncoder进行编码

ch.pipeline().addLast(newHttpRequestEncoder());

ch.pipeline().addLast(newHttpClientInboundHandler());

}

});//Start the client.

ChannelFuture f =b.connect(host, port).sync();

URI uri= new URI("http://127.0.0.1:8844");

String msg= "Are you ok?";

DefaultFullHttpRequest request= newDefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET,

uri.toASCIIString(), Unpooled.wrappedBuffer(msg.getBytes("UTF-8")));//构建http请求

request.headers().set(HttpHeaders.Names.HOST, host);

request.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE);

request.headers().set(HttpHeaders.Names.CONTENT_LENGTH, request.content().readableBytes());//发送http请求

f.channel().write(request);

f.channel().flush();

f.channel().closeFuture().sync();

}finally{

workerGroup.shutdownGracefully();

}

}public static void main(String[] args) throwsException {

HttpClient client= newHttpClient();

client.connect("127.0.0.1", 8844);

}

}

处理Server响应的HttpClientInboundHandler:

packagecom.netty.test;importio.netty.buffer.ByteBuf;importio.netty.channel.ChannelHandlerContext;importio.netty.channel.ChannelInboundHandlerAdapter;importio.netty.handler.codec.http.HttpContent;importio.netty.handler.codec.http.HttpHeaders;importio.netty.handler.codec.http.HttpResponse;public class HttpClientInboundHandler extendsChannelInboundHandlerAdapter {

@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throwsException {if (msg instanceofHttpResponse)

{

HttpResponse response=(HttpResponse) msg;

System.out.println("CONTENT_TYPE:" +response.headers().get(HttpHeaders.Names.CONTENT_TYPE));

}if(msg instanceofHttpContent)

{

HttpContent content=(HttpContent)msg;

ByteBuf buf=content.content();

System.out.println(buf.toString(io.netty.util.CharsetUtil.UTF_8));

buf.release();

}

}

}

参考:

https://github.com/netty/netty

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值