Netty--Http请求处理
1.这几天在看Netty权威指南,代码敲了一下,就当做个笔记吧。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
/** * Http服务端 * @author Tang * 2018年5月13日 */ 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 ); } } |
业务处理逻辑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
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); } /** * 获取传递的参数 * * @param ctx * @param fullHttpRequest * @return * @throws UnsupportedEncodingException */ 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
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; /** * An HTTP server that sends back the content of the received HTTP request * in a pretty plaintext form. */ 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(); } } } |
以上为个人经验,希望能给大家一个参考,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/BtWangZhi/article/details/80303577