Netty--Http请求处理
1.这几天在看Netty权威指南,代码敲了一下,就当做个笔记吧。
public class HttpServer {
public void run(String url,Integer port) {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup);
bootstrap.channel(NioServerSocketChannel.class);
bootstrap.childHandler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast("http-decoder", new HttpRequestDecoder());
ch.pipeline().addLast("http-aggregator",
new HttpObjectAggregator(65536));
ch.pipeline()
.addLast("http-encoder", new HttpResponseEncoder());
ch.pipeline()
.addLast("http-chunked", new ChunkedWriteHandler());
ch.pipeline().addLast("http-handler", new HttpServerHandler());
}
});
try {
ChannelFuture channelFuture = bootstrap.bind(url, port).sync();
channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
public static void main(String[] args) {
new HttpServer().run("127.0.0.1",8001);
}
}
业务处理逻辑
public class HttpServerHandler extends
SimpleChannelInboundHandler<FullHttpRequest> {
@Override
protected void messageReceived(ChannelHandlerContext ctx,
FullHttpRequest fullHttpRequest) throws Exception {
// 构造返回数据
JSONObject jsonRootObj = new JSONObject();
JSONObject jsonUserInfo = new JSONObject();
jsonUserInfo.put("id", 1);
jsonUserInfo.put("name", "张三");
jsonUserInfo.put("password", "123");
jsonRootObj.put("userInfo", jsonUserInfo);
// 获取传递的数据
Map<String, Object> params = getParamsFromChannel(ctx, fullHttpRequest);
jsonRootObj.put("params", params);
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK);
response.headers().set(CONTENT_TYPE, "application/json; charset=UTF-8");
StringBuilder bufRespose = new StringBuilder();
bufRespose.append(jsonRootObj.toJSONString());
ByteBuf buffer = Unpooled.copiedBuffer(bufRespose, CharsetUtil.UTF_8);
response.content().writeBytes(buffer);
buffer.release();
ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
}
private static Map<String, Object> getParamsFromChannel(
ChannelHandlerContext ctx, FullHttpRequest fullHttpRequest)
throws UnsupportedEncodingException {
HttpHeaders headers = fullHttpRequest.headers();
String strContentType = headers.get("Content-Type").trim();
System.out.println("ContentType:" + strContentType);
Map<String, Object> mapReturnData = new HashMap<String, Object>();
if (fullHttpRequest.getMethod() == HttpMethod.GET) {
// 处理get请求
QueryStringDecoder decoder = new QueryStringDecoder(
fullHttpRequest.getUri());
Map<String, List<String>> parame = decoder.parameters();
for (Entry<String, List<String>> entry : parame.entrySet()) {
mapReturnData.put(entry.getKey(), entry.getValue().get(0));
}
System.out.println("GET方式:" + parame.toString());
} else if (fullHttpRequest.getMethod() == HttpMethod.POST) {
// 处理POST请求
if (strContentType.contains("x-www-form-urlencoded")) {
HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(
new DefaultHttpDataFactory(false), fullHttpRequest);
List<InterfaceHttpData> postData = decoder.getBodyHttpDatas();
for (InterfaceHttpData data : postData) {
if (data.getHttpDataType() == HttpDataType.Attribute) {
MemoryAttribute attribute = (MemoryAttribute) data;
mapReturnData.put(attribute.getName(),
attribute.getValue());
}
}
} else if (strContentType.contains("application/json")) {
// 解析json数据
ByteBuf content = fullHttpRequest.content();
byte[] reqContent = new byte[content.readableBytes()];
content.readBytes(reqContent);
String strContent = new String(reqContent, "UTF-8");
System.out.println("接收到的消息" + strContent);
JSONObject jsonParamRoot = JSONObject.parseObject(strContent);
for (String key : jsonParamRoot.keySet()) {
mapReturnData.put(key, jsonParamRoot.get(key));
}
} else {
FullHttpResponse response = new DefaultFullHttpResponse(
HTTP_1_1, HttpResponseStatus.INTERNAL_SERVER_ERROR);
ctx.writeAndFlush(response).addListener(
ChannelFutureListener.CLOSE);
}
System.out.println("POST方式:" + mapReturnData.toString());
}
return mapReturnData;
}
}
支持Get和PostContentType为application/json、x-www-form-urlencoded的处理。
用Postman亲测无问题。
Netty处理简单Http请求的例子
废话不多说 上代码
HttpHelloWorldServerInitializer.java
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.ssl.SslContext;
public class HttpHelloWorldServerInitializer extends ChannelInitializer<SocketChannel> {
private final SslContext sslCtx;
public HttpHelloWorldServerInitializer(SslContext sslCtx) {
this.sslCtx = sslCtx;
}
@Override
public void initChannel(SocketChannel ch) {
ChannelPipeline p = ch.pipeline();
if (sslCtx != null) {
p.addLast(sslCtx.newHandler(ch.alloc()));
}
p.addLast(new HttpServerCodec());
p.addLast(new HttpHelloWorldServerHandler());
}
}
HttpHelloWorldServerHandler.java
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.HttpHeaderUtil;
import io.netty.handler.codec.http.HttpHeaderValues;
import io.netty.handler.codec.http.HttpRequest;
import static io.netty.handler.codec.http.HttpHeaderNames.*;
import static io.netty.handler.codec.http.HttpResponseStatus.*;
import static io.netty.handler.codec.http.HttpVersion.*;
public class HttpHelloWorldServerHandler extends ChannelHandlerAdapter {
private static final byte[] CONTENT = { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd' };
@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
ctx.flush();
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof HttpRequest) {
HttpRequest req = (HttpRequest) msg;
if (HttpHeaderUtil.is100ContinueExpected(req)) {
ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE));
}
boolean keepAlive = HttpHeaderUtil.isKeepAlive(req);
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(CONTENT));
response.headers().set(CONTENT_TYPE, "text/plain");
response.headers().setInt(CONTENT_LENGTH, response.content().readableBytes());
if (!keepAlive) {
ctx.write(response).addListener(ChannelFutureListener.CLOSE);
} else {
response.headers().set(CONNECTION, HttpHeaderValues.KEEP_ALIVE);
ctx.write(response);
}
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
HttpHelloWorldServer.java
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.util.SelfSignedCertificate;
public final class HttpHelloWorldServer {
static final boolean SSL = System.getProperty("ssl") != null;
static final int PORT = Integer.parseInt(System.getProperty("port", SSL? "8443" : "8080"));
public static void main(String[] args) throws Exception {
// Configure SSL.
final SslContext sslCtx;
if (SSL) {
SelfSignedCertificate ssc = new SelfSignedCertificate();
sslCtx = SslContext.newServerContext(ssc.certificate(), ssc.privateKey());
} else {
sslCtx = null;
}
// Configure the server.
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.option(ChannelOption.SO_BACKLOG, 1024);
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new HttpHelloWorldServerInitializer(sslCtx));
Channel ch = b.bind(PORT).sync().channel();
System.err.println("Open your web browser and navigate to " +
(SSL? "https" : "http") + "://127.0.0.1:" + PORT + '/');
ch.closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。