關(guān)于Netty--Http請(qǐng)求處理方式
Netty--Http請(qǐng)求處理
1.這幾天在看Netty權(quán)威指南,代碼敲了一下,就當(dāng)做個(gè)筆記吧。
/** * Http服務(wù)端 * @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); } }
業(yè)務(wù)處理邏輯
public class HttpServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> { @Override protected void messageReceived(ChannelHandlerContext ctx, FullHttpRequest fullHttpRequest) throws Exception { // 構(gòu)造返回?cái)?shù)據(jù) JSONObject jsonRootObj = new JSONObject(); JSONObject jsonUserInfo = new JSONObject(); jsonUserInfo.put("id", 1); jsonUserInfo.put("name", "張三"); jsonUserInfo.put("password", "123"); jsonRootObj.put("userInfo", jsonUserInfo); // 獲取傳遞的數(shù)據(jù) 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); } /** * 獲取傳遞的參數(shù) * * @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請(qǐng)求 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請(qǐng)求 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數(shù)據(jù) 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親測(cè)無問題。
Netty處理簡(jiǎn)單Http請(qǐng)求的例子
廢話不多說 上代碼
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; /** * 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(); } } }
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java 8 Stream.distinct() 列表去重的操作
這篇文章主要介紹了Java 8 Stream.distinct() 列表去重的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-12-12DolphinScheduler容錯(cuò)源碼分析之Worker
這篇文章主要為大家介紹了DolphinScheduler容錯(cuò)源碼分析之Worker,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02Java異步編程的5種異步實(shí)現(xiàn)方式詳解
這篇文章主要介紹了Java異步編程的5種異步實(shí)現(xiàn)方式詳解,異步編程是程序并發(fā)運(yùn)行的一種手段,它允許多個(gè)事件同時(shí)發(fā)生,當(dāng)程序調(diào)用需要長時(shí)間運(yùn)行的方法時(shí),它不會(huì)阻塞當(dāng)前的執(zhí)行流程,程序可以繼續(xù)運(yùn)行,需要的朋友可以參考下2024-01-01java發(fā)起http請(qǐng)求調(diào)用post與get接口的方法實(shí)例
在實(shí)際開發(fā)過程中,我們經(jīng)常需要調(diào)用對(duì)方提供的接口或測(cè)試自己寫的接口是否合適,下面這篇文章主要給大家介紹了關(guān)于java發(fā)起http請(qǐng)求調(diào)用post與get接口的相關(guān)資料,需要的朋友可以參考下2022-08-08java微信公眾號(hào)支付開發(fā)之現(xiàn)金紅包
這篇文章主要為大家詳細(xì)介紹了java微信公眾號(hào)支付開發(fā)之現(xiàn)金紅包,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04Java中sleep()與wait()的區(qū)別總結(jié)
因?yàn)樽罱鼘W(xué)習(xí)時(shí)正好碰到這兩個(gè)方法,就查閱相關(guān)資料,并通過程序?qū)崿F(xiàn),進(jìn)行區(qū)別總結(jié)一下,所以下面這篇文章主要給大家總結(jié)介紹了關(guān)于Java中sleep()與wait()區(qū)別的相關(guān)資料,需要的朋友可以參考,下面來一起看看吧。2017-05-05SpringCloud?Gateway詳細(xì)分析實(shí)現(xiàn)負(fù)載均衡與熔斷和限流
這篇文章主要介紹了SpringCloud?Gateway實(shí)現(xiàn)路由轉(zhuǎn)發(fā),負(fù)載均衡,熔斷和限流,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07